function handle_submission($action, $sitewide = false, $customize_defaults = false)
 {
     if ($sitewide || $customize_defaults) {
         if (function_exists('is_super_admin') && !is_super_admin()) {
             wp_die(__awp('Cheatin’ uh?'));
         }
     }
     if ($customize_defaults) {
         $sitewide = true;
     }
     // default customization is only for per-blog options, but is sitewide in terms of DB storage in sitemeta table
     if ('flush' == $action) {
         wpp_cache_flush_all_sites();
         return;
     }
     if (!in_array($_GET["page"], array('rs-options', 'rs-site_options', 'rs-default_options'))) {
         return;
     }
     if (empty($_POST['rs_submission_topic'])) {
         return;
     }
     if ('options' == $_POST['rs_submission_topic']) {
         if (!is_option_administrator_rs()) {
             wp_die(__awp('Cheatin’ uh?'));
         }
         scoper_refresh_default_options();
         scoper_refresh_default_otype_options();
         $method = "{$action}_options";
         if (method_exists($this, $method)) {
             call_user_func(array($this, $method), $sitewide, $customize_defaults);
         }
         $method = "{$action}_realm";
         if (method_exists($this, $method)) {
             call_user_func(array($this, $method), $sitewide, $customize_defaults);
         }
         if ($sitewide && !$customize_defaults) {
             $method = "{$action}_sitewide";
             if (method_exists($this, $method)) {
                 call_user_func(array($this, $method));
             }
         }
         if (isset($_POST['rs_role_defs']) && empty($_POST['rs_defaults'])) {
             if ($customize_defaults) {
                 $function = 'update_rs_role_defs_customize_defaults';
             } elseif ($sitewide) {
                 $function = 'update_rs_role_defs_sitewide';
             } else {
                 $function = 'update_rs_role_defs';
             }
             add_action('init', array(&$this, $function), 20);
             // this must execute after other plugins have added rs config filters
         }
     }
     scoper_refresh_options();
     // force DB schema update if sitewide_groups option was changed
     require SCOPER_ABSPATH . '/db-config_rs.php';
 }
 function flt_manage_posts_custom_column($column_name, $id)
 {
     global $scoper, $scoper_role_usage, $posts;
     switch ($column_name) {
         case 'restricted':
             $restricted_ops = array();
             if (isset($scoper_role_usage->objscoped_ids['post'][$id]['read'])) {
                 $restricted_ops[] = '<strong>' . __('Read', 'scoper') . '</strong>';
             } elseif (isset($scoper_role_usage->termscoped_ids['post'][$id]['read'])) {
                 $restricted_ops[] = __('Read', 'scoper');
             }
             if (isset($scoper_role_usage->objscoped_ids['post'][$id]['edit'])) {
                 $restricted_ops[] = '<strong>' . __awp('Edit') . '</strong>';
             } elseif (isset($scoper_role_usage->termscoped_ids['post'][$id]['edit'])) {
                 $restricted_ops[] = __awp('Edit');
             }
             if ($restricted_ops) {
                 echo implode(", ", $restricted_ops);
             }
             break;
         case 'termroles':
             $role_names = array();
             if (isset($scoper_role_usage->have_termrole_ids['post'][$id])) {
                 foreach (array_keys($scoper_role_usage->have_termrole_ids['post'][$id]) as $role_handle) {
                     $role_names[] = str_replace(' ', '&nbsp;', $scoper->role_defs->get_micro_abbrev($role_handle));
                 }
                 sort($role_names);
                 echo implode(", ", $role_names);
             }
             break;
         case 'objroles':
             $role_names = array();
             if (isset($scoper_role_usage->have_objrole_ids['post'][$id])) {
                 foreach (array_keys($scoper_role_usage->have_objrole_ids['post'][$id]) as $role_handle) {
                     $role_names[] = str_replace(' ', '&nbsp;', $scoper->role_defs->get_micro_abbrev($role_handle, OBJECT_UI_RS));
                 }
                 sort($role_names);
                 echo implode(", ", $role_names);
             }
             break;
     }
 }
function printGroupMembers()
{
    $results = ScoperAdminLib::get_all_groups(FILTERED_RS);
    $alt = false;
    if (isset($results) && count($results) > 0) {
        echo "\n<table class='rs-member_table' width=\"100%\" border=\"0\" cellspacing=\"3\" cellpadding=\"3\">";
        echo "\n\t<tr class=\"thead\">";
        echo "\n\t\t<th>Group Name</th>\n\t\t<th>Members</th>\n\t\t<th>&nbsp;</th>";
        echo "\n\t</tr>";
        foreach ($results as $result) {
            $alt = !$alt;
            $style = $alt ? 'class=\'alternate\'' : 'margin: 1em 0 1em 0;';
            echo "<tr " . $style . "><td>" . $result->display_name . "</td><td>";
            if ($members = ScoperAdminLib::get_group_members($result->ID)) {
                printf(_n('%d user', '%d users', count($members), 'scoper'), count($members));
                echo '<br />';
                foreach ($members as $member) {
                    echo "- " . $member->display_name . "<br />";
                }
            } else {
                if ($result->meta_id) {
                    _e('(automatic)', 'scoper');
                } else {
                    _e('(no users)', 'scoper');
                }
            }
            echo "</td><td " . $style . ">";
            if (!$result->meta_id) {
                echo "<a class='edit' href='admin.php?page=rs-group_members&amp;mode=edit&amp;id={$result->ID}'>" . __awp('Edit') . "</a>";
            }
            echo "</td></tr>";
        }
        echo "\n</table>";
    } else {
        echo "<p><strong>" . __('No groups available.', 'scoper') . "</strong></p>";
    }
}
    function item_tree($scope, $mode, $src, $otype_or_tx, $all_items, $assigned_roles, $strict_items, $role_defs_by_otype, $role_codes, $args = array())
    {
        $defaults = array('admin_items' => '', 'editable_roles' => '', 'ul_class' => 'rs-termlist', 'ie_link_style' => '', 'object_names' => '', 'table_captions' => '', 'err' => '', 'object_status' => '', 'agent_caption_plural' => '', 'agent_list_prefix' => '', 'agent_names' => '', 'default_hide_empty' => false, 'role_bases' => array(ROLE_BASIS_USER, ROLE_BASIS_GROUPS), 'single_item' => false);
        $args = array_merge($defaults, (array) $args);
        extract($args);
        global $scoper;
        if (!is_object($src)) {
            $src = $scoper->data_sources->get($src);
        }
        $col_id = $src->cols->id;
        $col_name = $src->cols->name;
        $col_parent = isset($src->cols->parent) ? $src->cols->parent : '';
        $item_label = $otype_or_tx->labels->singular_name;
        if (TERM_SCOPE_RS == $scope) {
            $src_or_tx_name = $otype_or_tx->name;
            $edit_url_base = !empty($otype_or_tx->edit_url) ? $otype_or_tx->edit_url : '';
        } else {
            $src_or_tx_name = $src->name;
            $edit_url_base = !empty($src->edit_url) ? $src->edit_url : '';
        }
        if ($default_hide_empty) {
            $hide_tr_sfx = '-hide';
            $hide_li_sfx = '-hide';
        } else {
            $hide_tr_sfx = '';
            $hide_li_sfx = '';
        }
        $nextlink = '';
        $prevlink = '';
        if (empty($admin_items)) {
            $admin_items = array();
        }
        if (empty($agent_caption_plural)) {
            $agent_caption_plural = __('Users or Groups', 'scoper');
        }
        if (empty($agent_list_prefix)) {
            $agent_list_prefix = array();
            $agent_list_prefix[ROLE_BASIS_USER] = '';
            $agent_list_prefix[ROLE_BASIS_GROUPS] = __('Groups') . ': ';
        }
        static $prevtext, $nexttext, $is_administrator, $role_header, $agents_header;
        if (empty($prevtext)) {
            // buffer prev/next caption for display with each term
            //$prevtext = _ x('prev', '|abbreviated link to previous item', 'scoper');
            //$nexttext = _ x('next', '|abbreviated link to next item', 'scoper');
            $prevtext = __('prev', 'scoper');
            $nexttext = __('next', 'scoper');
            $is_administrator = is_administrator_rs($src, 'user');
            $role_header = __awp('Role');
            switch ($mode) {
                case ROLE_ASSIGNMENT_RS:
                    //$agents_header = sprintf( _ x('Current %s', 'users or groups', 'scoper'), $agent_caption_plural);
                    $agents_header = sprintf(__('Current %s', 'scoper'), $agent_caption_plural);
                    break;
                case ROLE_RESTRICTION_RS:
                    $agents_header = __('Current Restrictions', 'scoper');
                    break;
                default:
                    return;
            }
        }
        // disregard roles that don't apply to this scope
        foreach ($role_defs_by_otype as $object_type => $role_defs) {
            foreach ($role_defs as $role_handle => $role) {
                if (!isset($role->valid_scopes[$scope])) {
                    unset($role_defs_by_otype[$object_type][$role_handle]);
                }
            }
        }
        // for object scope, assign "private post reader" role, but label it as "post reader" to limit confusion
        $role_display_name = array();
        foreach ($role_defs_by_otype as $role_defs) {
            foreach (array_keys($role_defs) as $role_handle) {
                $role_display_name[$role_handle] = $scoper->role_defs->get_display_name($role_handle, $scope . '_ui');
            }
        }
        // display a separate role assignment list for each individual term / object
        $last_id = -1;
        $last_name = '';
        $last_parent_id = -1;
        $parent_id = 0;
        $parents = array();
        $depth = 0;
        $_top_link = "<a{$ie_link_style} href='#scoper_top'>" . __('top', 'scoper') . '</a>';
        $tr_display = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false ? 'block' : 'table-row';
        $show_all_caption = __('show all', 'scoper');
        echo "<ul class='{$ul_class}' style='padding-left:0.1em;'>";
        if (empty($all_items)) {
            $all_items = array();
        }
        if (!$single_item && is_user_administrator_rs() && 'nav_menu' != $src_or_tx_name) {
            // TODO: action handler for new menu item storage
            if (ROLE_ASSIGNMENT_RS == $mode) {
                $root_caption = sprintf(__('DEFAULTS for new %s', 'scoper'), $otype_or_tx->labels->name);
            } else {
                $root_caption = sprintf(__('DEFAULTS for all %s', 'scoper'), $otype_or_tx->labels->name);
            }
            if (TERM_SCOPE_RS == $scope) {
                $root_item = (object) array($col_id => 0, $col_name => $root_caption, $col_parent => 0);
                array_unshift($all_items, $root_item);
            } else {
                $obj = (object) array($col_id => 0);
                $all_items = array($root_caption => $obj) + $all_items;
                $object_names[0] = $root_caption;
                $status_objects = 'post' == $src->name ? get_post_stati(array(), 'object') : array();
            }
        }
        $title_roles = __('edit roles', 'scoper');
        $title_item = sprintf(__('edit %s', 'scoper'), agp_strtolower($item_label));
        foreach ($all_items as $key => $item) {
            $id = $item->{$col_id};
            if (!empty($object_names[$id])) {
                $name = esc_attr(str_replace(' ', '&nbsp;', $object_names[$id]));
            } else {
                $name = str_replace(' ', '&nbsp;', $item->{$col_name});
            }
            if ($col_parent && isset($item->{$col_parent})) {
                $parent_id = $item->{$col_parent};
                if ($parent_id != $last_parent_id) {
                    if ($parent_id == $last_id && $last_id) {
                        $parents[$last_name] = $last_id;
                        echo "<ul class='{$ul_class}'>";
                        $depth++;
                    } elseif ($depth) {
                        do {
                            //echo "term $name: depth $depth, current parents: " . print_r($parents);
                            array_pop($parents);
                            echo '</li></ul>';
                            $depth--;
                        } while ($parents && end($parents) != $parent_id && $depth);
                    }
                    $last_parent_id = $parent_id;
                }
            }
            if ($is_administrator || isset($admin_items[$last_id])) {
                if (!$last_id) {
                    // always close li for defaults
                    echo '</li>';
                } elseif (-1 != $last_id && $parent_id != $last_id) {
                    echo '</li>';
                }
            }
            if (OBJECT_SCOPE_RS == $scope) {
                if (isset($object_status) && !empty($object_status[$id]) && 'publish' != $object_status[$id] && 'private' != $object_status[$id]) {
                    $status_text = isset($status_objects[$object_status[$id]]) ? "{$status_objects[$object_status[$id]]->label}, " : "{$object_status[$id]}, ";
                } else {
                    $status_text = '';
                }
                $link_span_open = $status_text ? "<span class='rs-brown'>" : '';
                $link_span_close = $status_text ? "</span>" : '';
                // link from object name to our "Edit Object Role Assignment" interface
                if ($id) {
                    $rs_edit_url = "admin.php?page=rs-object_role_edit&amp;src_name={$src_or_tx_name}&amp;object_type={$otype_or_tx->name}&amp;object_id={$id}&amp;object_name=" . urlencode($name);
                    $name_text = "{$link_span_open}<a title='{$title_roles}' href='{$rs_edit_url}'>{$name}</a>{$link_span_close}";
                } else {
                    $name_text = $name;
                }
                // link from object ID to the object type's default editor, if defined
                if ($id && $edit_url_base) {
                    $content_edit_url = sprintf($edit_url_base, $id);
                    $id_text = "<a title='{$title_item}' href='{$content_edit_url}' class='edit'>{$id}</a>";
                } else {
                    $id_text = $id;
                }
                $id_text = $id ? " ({$status_text}" . sprintf(__('id %s', 'scoper'), $id_text) . ')' : '';
            } elseif ($id && TERM_SCOPE_RS == $scope && $edit_url_base) {
                $content_edit_url = sprintf($edit_url_base, $id);
                $name_text = "<a class='rs-dlink_rev' href='{$content_edit_url}' title='{$title_item}'>{$name}</a>";
                $id_text = '';
            } else {
                $name_text = $name;
                $id_text = '';
            }
            //display scroll links for this term
            if (TERM_SCOPE_RS == $scope) {
                $prevlink = $last_id && !$single_item && $id ? "<a{$ie_link_style} href='#item-" . $last_id . "'>" . $prevtext . "</a>" : '';
            }
            if ($id && (!$is_administrator && !isset($admin_items[$id]))) {
                continue;
            }
            $last_id = $id;
            $last_name = $name;
            $next_id = $id && isset($all_items[$key + 1]) ? $all_items[$key + 1]->{$col_id} : 0;
            if (TERM_SCOPE_RS == $scope) {
                if ($next_id) {
                    $nextlink = "<a{$ie_link_style} href='#item-" . $next_id . "'>" . $nexttext . "</a>";
                } elseif ($id) {
                    $nextlink = "<span class='rs-termlist_linkspacer'>{$nexttext}</span>";
                } else {
                    $nextlink = '';
                }
            }
            if ($parents) {
                //$color_class = ( TERM_SCOPE_RS == $scope ) ? 'rs-lgray' : 'rs-gray';
                //$item_path = "<span class='$color_class'>" . implode(' / ', array_keys($parents)) . ' / ' . '</span>';
                $item_path = implode(' / ', array_keys($parents)) . ' / ';
                $margin = '';
                $top_pad = '1.5em';
            } else {
                $item_path = '';
                $margin = 'margin-top:2em;';
                $top_pad = '0.2em';
            }
            $js_call = "agp_toggle_display('roles-{$id}','block','tgl-{$id}', '-', '+');" . "agp_toggle_display('jump-{$id}','block');";
            $role_class = '';
            if ($id) {
                // never hide defaults block
                if (ROLE_ASSIGNMENT_RS == $mode) {
                    $role_class = '';
                    if (!isset($assigned_roles[ROLE_BASIS_USER][$id]) && !isset($assigned_roles[ROLE_BASIS_GROUPS][$id])) {
                        $role_class = " no-rol-li{$hide_li_sfx}";
                    } elseif (!isset($assigned_roles[ROLE_BASIS_USER][$id])) {
                        $role_class = " no-user-li";
                    } elseif (!isset($assigned_roles[ROLE_BASIS_GROUPS][$id])) {
                        $role_class = " no-groups-li";
                    }
                } elseif (ROLE_RESTRICTION_RS == $mode) {
                    $role_class = " no-rol-li{$hide_li_sfx}";
                    $setting_types = array('restrictions', 'unrestrictions');
                    foreach ($setting_types as $setting_type) {
                        if (isset($strict_items[$setting_type])) {
                            foreach (array_keys($strict_items[$setting_type]) as $role_handle) {
                                // key is role_handle
                                if (isset($strict_items[$setting_type][$role_handle][$id])) {
                                    $role_class = '';
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            $class = $role_class ? "class='" . trim($role_class) . "' " : '';
            echo "\r\n\r\n<li {$class}style='padding:{$top_pad} 0.5em 0 0.3em;{$margin}'>";
            if (!$single_item) {
                $top_link = $id ? $_top_link : '';
                echo "<a name='item-{$id}'></a>" . "<span id='jump-{$id}' class='rs-termjump alignright'>{$prevlink}{$nextlink}" . $top_link . '</span>' . "<strong><a class='rs-link_plain_rev term-tgl' id='tgl-{$id}' href='javascript:void(0);' onclick=\"{$js_call}\" title=\"{$otype_or_tx->labels->singular_name} {$id}: {$name}\">" . "-</a></strong> " . $item_path . '<strong>' . $name_text . '</strong>' . $id_text . ': ';
            }
            echo "</li><li id='roles-{$id}' class='role-li{$role_class}'>";
            ?>

<table class='rs-widefat rs-role-tbl'>
<thead>
<tr class="thead">
	<th class="rs-tightcol"><?php 
            $js_call = "agp_display_child_nodes( 'tbl-{$id}', 'TR', '{$tr_display}' );";
            echo "<a href='javascript:void(0);' title='{$show_all_caption}' onclick=\"{$js_call}\">+</a>";
            ?>
</th>
	<th class="rs-tightcol"><?php 
            echo $role_header;
            ?>
</th>
	<th><?php 
            echo $agents_header;
            ?>
</th>
</tr>
</thead>
<tbody id='<?php 
            echo "tbl-{$id}";
            ?>
'>
<?php 
            // display each role eligible for group/user assignment in this term/object
            foreach ($role_defs_by_otype as $object_type => $role_defs) {
                $vals = array();
                $ids = array();
                if (!$single_item) {
                    foreach (array_keys($role_defs) as $role_handle) {
                        // retain previous selections in case of error ( user forgets to select groups/users )
                        $vals[$role_handle] = "{$role_codes[$role_handle]}-{$id}";
                        // pre-generate all checkbox ids in this op_type, to pass to javascript
                        $ids[$role_handle] = 'rs-' . $vals[$role_handle];
                    }
                }
                foreach (array_keys($role_defs) as $role_handle) {
                    // Does current user have this role?
                    if (!$single_item && ($is_administrator || !is_array($editable_roles) || !empty($editable_roles[0][$role_handle]) || !empty($editable_roles[$id][$role_handle]))) {
                        $form_id = $id || ROLE_ASSIGNMENT_RS == $mode ? 'roles' : 'default_restrictions';
                        $checked = $err && isset($_POST[$form_id]) && in_array($vals[$role_handle], $_POST[$form_id]) ? 'checked="checked"' : '';
                        if (ROLE_ASSIGNMENT_RS == $mode) {
                            //$skip_if_id = 'assign_for';	// reduced html bulk by making 3rd & 4th args of agp_uncheck default to these values
                            //$skip_if_val = REMOVE_ASSIGNMENT_RS;
                            $js_call = "agp_uncheck('" . implode(',', $ids) . "',this.id);";
                            $onclick = "onclick=\"{$js_call}\"";
                        } else {
                            $onclick = '';
                        }
                        $checkbox = "<input type='checkbox' name='{$form_id}[]' id='{$ids[$role_handle]}' value='{$vals[$role_handle]}' {$checked} {$onclick} />";
                        $label = "<label for='{$ids[$role_handle]}'>" . str_replace(' ', '&nbsp;', $role_display_name[$role_handle]) . "</label>";
                    } else {
                        $checkbox = '';
                        $label = str_replace(' ', '&nbsp;', $role_display_name[$role_handle]);
                    }
                    $classes = array();
                    if ($default_strict = isset($strict_items['unrestrictions'][$role_handle]) && is_array($strict_items['unrestrictions'][$role_handle])) {
                        $setting = 'unrestrictions';
                    } else {
                        $setting = 'restrictions';
                    }
                    if (isset($strict_items[$setting][$role_handle][$id])) {
                        if ($single_item) {
                            $require_for = $strict_items[$setting][$role_handle][$id];
                            $open_brace = $close_brace = '';
                        } else {
                            $require_for = $strict_items[$setting][$role_handle][$id]['assign_for'];
                            $open_brace = $strict_items[$setting][$role_handle][$id]['inherited_from'] ? '{' : '';
                            $close_brace = $open_brace ? '}' : '';
                        }
                    } else {
                        $require_for = false;
                        $open_brace = $close_brace = '';
                    }
                    switch ($mode) {
                        case ROLE_ASSIGNMENT_RS:
                            $open_brace = $close_brace = '';
                            $assignment_list = array();
                            foreach ($role_bases as $role_basis) {
                                if (isset($assigned_roles[$role_basis][$id][$role_handle])) {
                                    $checkbox_id = $single_item ? '' : $role_basis;
                                    $assignment_names = array_intersect_key($agent_names[$role_basis], $assigned_roles[$role_basis][$id][$role_handle]);
                                    $assignment_list[$role_basis] = "<span class='{$role_basis}-csv'><span class='rs-bold'>" . $agent_list_prefix[$role_basis] . '</span>' . ScoperAdminBulkLib::role_assignment_list($assigned_roles[$role_basis][$id][$role_handle], $assignment_names, $checkbox_id, $role_basis) . '</span>';
                                }
                            }
                            $setting_display = implode('&nbsp;&nbsp;', $assignment_list);
                            // don't hide rows for default roles
                            if ($id) {
                                if (!isset($assigned_roles[ROLE_BASIS_USER][$id][$role_handle]) && !isset($assigned_roles[ROLE_BASIS_GROUPS][$id][$role_handle])) {
                                    $classes[] = "no-rol{$hide_tr_sfx}";
                                } elseif (!isset($assigned_roles[ROLE_BASIS_USER][$id][$role_handle])) {
                                    $classes[] = "no-user";
                                } elseif (!isset($assigned_roles[ROLE_BASIS_GROUPS][$id][$role_handle])) {
                                    $classes[] = "no-groups";
                                }
                            }
                            break;
                        case ROLE_RESTRICTION_RS:
                            if (!$id) {
                                $setting_display = $table_captions[$setting]['default'];
                            } elseif ($require_for) {
                                $setting_display = $table_captions[$setting][$require_for];
                            } else {
                                $setting_display = '(' . $table_captions[$setting][false] . ')';
                                // don't hide rows for default restrictions
                                if ($id) {
                                    $classes[] = " no-rol{$hide_tr_sfx}";
                                }
                            }
                    }
                    // end switch $mode
                    switch ($require_for) {
                        case ASSIGN_FOR_BOTH_RS:
                            $open_brace = '<span class="rs-bold">' . $open_brace;
                            $close_brace .= '</span>';
                            break;
                        case ASSIGN_FOR_CHILDREN_RS:
                            $open_brace = '<span class="rs-gray">' . $open_brace;
                            $close_brace .= '</span>';
                    }
                    // end switch
                    if (empty($default_strict) && $require_for && $require_for != ASSIGN_FOR_CHILDREN_RS || !empty($default_strict) && !$require_for) {
                        $classes[] = 'rs-backylw';
                    }
                    $class = $classes ? " class='" . implode(' ', $classes) . "'" : '';
                    echo "\r\n" . "<tr{$class}>" . "<td>{$checkbox}</td>" . "<td>{$label}</td>" . "<td>{$open_brace}{$setting_display}{$close_brace}</td>" . "</tr>";
                }
                // end foreach role
            }
            // end foreach object_type
            echo '</tbody></table>';
        }
        // end foreach term
        while ($depth) {
            echo '</li></ul>';
            $depth--;
        }
        echo '</li>';
        echo '</ul><br /><ul>';
        // now display "select all" checkboxes for all terms in this taxonomy
        if (empty($single_item)) {
            if (defined('SCOPER_EXTRA_SUBMIT_BUTTON')) {
                echo '<li class="alignright"><span class="submit" style="border:none;"><input type="submit" name="rs_submit" value="' . __('Update &raquo;', 'scoper') . '" /></span></li>';
            }
            ?>

		<li><table class='widefat' style='width:auto;'>
		<thead>
		<tr class="thead">
		<th colspan="2"><?php 
            printf(__('select / unselect all:', 'scoper'), agp_strtolower($otype_or_tx->labels->name));
            ?>
</th>
		<!--<th colspan="2" style="text-align: center"><?php 
            _e('Actions');
            ?>
</th>-->
		</tr>
		</thead>
		<tbody id="bulk_roles-<?php 
            echo $otype_or_tx->name;
            ?>
">
<?php 
            //convert allterms stdobj to array for implosion
            $all_items_arr = array();
            foreach ($all_items as $item) {
                $all_items_arr[] = $item->{$col_id};
            }
            $all_items_ser = implode('-', $all_items_arr);
            //display "check for every term" shortcuts for each individual role
            global $scoper;
            $style = ' class="rs-backwhite"';
            foreach ($role_defs_by_otype as $object_type => $roles) {
                foreach (array_keys($roles) as $role_handle) {
                    $style = ' class="alternate"' == $style ? ' class="rs-backwhite"' : ' class="alternate"';
                    // $check_shorcut was displayed in first <td>
                    $id = "rs-Z-{$role_codes[$role_handle]}";
                    $caption = ' <span class="rs-subtext">' . sprintf(__('(all %s)', 'scoper'), agp_strtolower($otype_or_tx->labels->name)) . '</span>';
                    $js_call = "scoper_checkroles('{$id}', '{$all_items_ser}', '{$role_codes[$role_handle]}');";
                    echo "\n\t<tr {$style}>" . "<td><input type='checkbox' id='{$id}' onclick=\"{$js_call}\" /></td>" . "<td><label for='{$id}'>" . $scoper->role_defs->get_display_name($role_handle, $scope . '_ui') . "{$caption}</label></td>" . "</tr>";
                }
                // end foreach role
            }
            // end foreach roledef
            echo '</tbody></table></li></ul><br />';
        }
        // endif not single item
    }
 function role_owners_key($tx_or_otype, $args = array())
 {
     $defaults = array('display_links' => true, 'display_restriction_key' => true, 'restriction_caption' => '', 'role_basis' => '', 'agent_caption' => '', 'single_item' => false);
     $args = array_merge($defaults, (array) $args);
     extract($args);
     $item_label = agp_strtolower($tx_or_otype->labels->name);
     $item_label_singular = agp_strtolower($tx_or_otype->labels->singular_name);
     if ($role_basis) {
         if (!$agent_caption && $role_basis) {
             $agent_caption = ROLE_BASIS_GROUPS == $role_basis ? __('Group', 'scoper') : __('User', 'scoper');
         }
         $generic_name = ROLE_BASIS_GROUPS == $role_basis ? __('Groupname', 'scoper') : __('Username', 'scoper');
     } else {
         $generic_name = __awp('Name');
     }
     $agent_caption = agp_strtolower($agent_caption);
     if ($single_item) {
         echo '<div id="single_item_roles_key" style="display:none">';
         echo '<div style="margin-bottom:0.1em;margin-top:0"><strong><a name="scoper_key"></a>' . __("Users / Groups Key", 'scoper') . ':</strong></div><ul class="rs-agents_key">';
     } else {
         echo '<h4 style="margin-bottom:0.1em"><a name="scoper_key"></a>' . __("Users / Groups Key", 'scoper') . ':</h4><ul class="rs-agents_key">';
     }
     $link_open = $display_links ? "<a class='rs-link_plain' href='javascript:void(0)'>" : '';
     $link_close = $display_links ? '</a>' : '';
     echo '<li>';
     echo "{$link_open}{$generic_name}{$link_close}: ";
     printf(__('%1$s has role assigned for the specified %2$s.', 'scoper'), $agent_caption, $item_label_singular);
     echo '</li>';
     echo '<li>';
     echo "<span class='rs-bold'>{$link_open}{$generic_name}{$link_close}</span>: ";
     printf(__('%1$s has role assigned for the specified %2$s and, by default, for all its sub-%3$s. (Propagated roles can also be explicitly removed).', 'scoper'), $agent_caption, $item_label_singular, $item_label);
     echo '</li>';
     echo '<li>';
     echo "<span class='rs-bold rs-gray'>{$link_open}{$generic_name}{$link_close}</span>: ";
     printf(__('%1$s does NOT have role assigned for the specified %2$s, but has it by default for sub-%3$s.', 'scoper'), $agent_caption, $item_label_singular, $item_label);
     echo '</li>';
     echo '<li>';
     echo '<span class="rs-bold">{' . "{$link_open}{$generic_name}{$link_close}" . '}</span>: ';
     printf(__('%1$s has this role via propagation from parent %2$s, and by default for sub-%3$s.', 'scoper'), $agent_caption, $item_label_singular, $item_label);
     echo '</li>';
     if ($display_restriction_key) {
         echo '<li>';
         echo "<span class='rs-bold rs-backylw' style='border:1px solid #00a;padding-left:0.5em;padding-right:0.5em'>" . __('Role Name', 'scoper') . "</span>: ";
         echo "<span>" . sprintf(__('role is restricted for specified %s.', 'scoper'), $item_label_singular) . "</span>";
         echo '</li>';
     }
     echo '</ul>';
     if ($single_item) {
         echo '</div><br />';
     }
 }
 function flt_wp_dropdown_users($wp_output)
 {
     // just filter Post Author dropdown
     if (!strpos($wp_output, "name='post_author_override'")) {
         return $wp_output;
     }
     // this is meant to filter the post author selection
     if (!is_admin()) {
         return $wp_output;
     }
     // if (even after our blogcap tinkering) the author list is already locked due to insufficient blog-wide caps, don't mess
     if (!($pos = strpos($wp_output, '<option'))) {
         return $wp_output;
     }
     if (!strpos($wp_output, '<option', $pos + 1)) {
         return $wp_output;
     }
     global $wpdb, $scoper;
     $last_query = $wpdb->last_query;
     if (!($object_type = cr_find_post_type())) {
         return $wp_output;
     }
     if (!($post_type_obj = get_post_type_object($object_type))) {
         return $wp_output;
     }
     global $current_user;
     $is_ngg_edit = strpos($_SERVER['REQUEST_URI'], 'nggallery-manage-gallery');
     if (!$is_ngg_edit) {
         $src_name = 'post';
         $object_id = scoper_get_object_id('post', $object_type);
         // only modify the default authors list if current user has Editor role for the current post/page
         $have_cap = cr_user_can($post_type_obj->cap->edit_others_posts, $object_id, 0, array('require_full_object_role' => true));
     } else {
         $src_name = 'ngg_gallery';
         $object_id = $_REQUEST['gid'];
         $have_cap = !empty($current_user->allcaps[$post_type_obj->cap->edit_others_posts]);
         // $post_type_obj defaults to 'post' type on NGG Manage Gallery page
     }
     //if ( ! $have_cap )
     //	return $wp_output;
     $orderpos = strpos($last_query, 'ORDER BY');
     $orderby = $orderpos ? substr($last_query, $orderpos) : '';
     if (!strpos($orderby, 'display_name')) {
         // sanity check in case the last_query buffer gets messed up
         $orderby = '';
     }
     $id_in = $id_not_in = $show_option_all = $show_option_none = '';
     $pos = strpos($last_query, 'AND ID IN(');
     if ($pos) {
         $pos_close = strpos($last_query, ')', $pos);
         if ($pos_close) {
             $id_in = substr($last_query, $pos, $pos_close - $pos + 1);
         }
     }
     $pos = strpos($last_query, 'AND ID NOT IN(');
     if ($pos) {
         $pos_close = strpos($last_query, ')', $pos);
         if ($pos_close) {
             $id_not_in = substr($last_query, $pos, $pos_close - $pos + 1);
         }
     }
     $search = "<option value='0'>";
     $pos = strpos($wp_output, $search . __awp('Any'));
     if ($pos) {
         $pos_close = strpos($wp_output, '</option>', $pos);
         if ($pos_close) {
             $show_option_all = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search));
         }
     }
     $search = "<option value='-1'>";
     $pos = strpos($wp_output, $search . __awp('None'));
     if ($pos) {
         $pos_close = strpos($wp_output, '</option>', $pos);
         if ($pos_close) {
             $show_option_none = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search));
         }
     }
     $search = "<select name='";
     $pos = strpos($wp_output, $search);
     if (false !== $pos) {
         $pos_close = strpos($wp_output, "'", $pos + strlen($search));
         if ($pos_close) {
             $name = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search));
         }
     }
     $search = " id='";
     $multi = !strpos($wp_output, $search);
     // beginning with WP 2.7, some users dropdowns lack id attribute
     $search = " class='";
     $pos = strpos($wp_output, $search);
     if ($pos) {
         $pos_close = strpos($wp_output, "'", $pos + strlen($search));
         if ($pos_close) {
             $class = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search));
         }
     }
     $search = " selected='selected'";
     $pos = strpos($wp_output, $search);
     if ($pos) {
         $search = "<option value='";
         $str_left = substr($wp_output, 0, $pos);
         $pos = strrpos($str_left, $search);
         //back up to previous option tag
         $pos_close = strpos($wp_output, "'", $pos + strlen($search));
         if ($pos_close) {
             $selected = substr($wp_output, $pos + strlen($search), $pos_close - ($pos + strlen($search)));
         }
     }
     if (empty($selected)) {
         $selected = $current_user->ID;
     }
     // precaution prevents default-selection of non-current user
     // Role Scoper filter application
     $where = "{$id_in} {$id_not_in}";
     $args = array();
     $args['where'] = $where;
     $args['orderby'] = $orderby;
     if ($object_id > 0) {
         if ($current_author = $scoper->data_sources->get_from_db('owner', $src_name, $object_id)) {
             $force_user_id = $current_author;
         }
     } else {
         $force_user_id = $current_user->ID;
     }
     if ($have_cap) {
         if ($force_user_id) {
             $args['preserve_or_clause'] = " uro.user_id = '{$force_user_id}'";
         }
         $users = $scoper->users_who_can($post_type_obj->cap->edit_posts, COLS_ID_DISPLAYNAME_RS, 'post', $object_id, $args);
     } else {
         $display_name = $wpdb->get_var("SELECT display_name FROM {$wpdb->users} WHERE ID = '{$force_user_id}'");
         $users = array((object) array('ID' => $force_user_id, 'display_name' => $display_name));
     }
     if (empty($users)) {
         // sanity check: users_who_can should always return Administrators
         if ($admin_roles = awp_administrator_roles()) {
             $users = scoper_get_results("SELECT DISTINCT ID, display_name FROM {$wpdb->users} INNER JOIN {$wpdb->user2role2object_rs} AS uro ON uro.user_id = {$wpdb->users}.ID AND uro.scope = 'blog' AND uro.role_type = 'wp' AND uro.role_name IN ('" . implode("','", $admin_roles) . "')");
         } else {
             return $wp_output;
         }
         // the user data must be messed up
     }
     $show = 'display_name';
     // no way to back this out
     // ----------- begin wp_dropdown_users code copy (from WP 2.7) -------------
     $id = $multi ? "" : "id='{$name}'";
     $output = "<select name='{$name}' {$id} class='{$class}'>\n";
     if ($show_option_all) {
         $output .= "\t<option value='0'>{$show_option_all}</option>\n";
     }
     if ($show_option_none) {
         $output .= "\t<option value='-1'>{$show_option_none}</option>\n";
     }
     foreach ((array) $users as $user) {
         $user->ID = (int) $user->ID;
         $_selected = $user->ID == $selected ? " selected='selected'" : '';
         $display = !empty($user->{$show}) ? $user->{$show} : '(' . $user->user_login . ')';
         $output .= "\t<option value='{$user->ID}'{$_selected}>" . esc_html($display) . "</option>\n";
     }
     $output .= "</select>";
     // ----------- end wp_dropdown_users code copy (from WP 2.7) -------------
     return $output;
 }
 function install_strings($plugin)
 {
     if ($title = ucwords(str_replace('-', ' ', $plugin))) {
         $this->strings['no_package'] = __awp('Install package not available.');
         $this->strings['downloading_package'] = sprintf(__awp('Downloading install package from <span class="code">%s</span>&#8230;'), untrailingslashit('http://presspermit.com/'));
         $this->strings['unpack_package'] = __awp('Unpacking the package&#8230;');
         $this->strings['installing_package'] = __awp('Installing the plugin&#8230;');
         $this->strings['process_failed'] = sprintf(__awp('%s install Failed.', 'pp'), $title);
         $this->strings['process_success'] = sprintf(__awp('%s installed successfully.', 'pp'), $title);
     }
 }
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(' ', '&nbsp;', 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 '&nbsp;';
    _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&#8217; 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&amp;src_name={$src_name}&amp;object_type={$object_type}&amp;object_id={$obj_id}&amp;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 draw_object_roles_content($src_name, $object_type, $role_handle, $object_id = '', $skip_user_validation = false, $object = false)
 {
     //log_mem_usage_rs( 'start ItemRolesUI::draw_object_roles_content()' );
     if (!$object_id) {
         $object_id = scoper_get_object_id($src_name, $object_type);
     }
     if (!empty($object) && 'auto-draft' == $object->post_status) {
         $object_id = 0;
     }
     if ($src_name != $this->loaded_src_name || $object_type != $this->loaded_object_type || $object_id != $this->loaded_object_id) {
         $this->load_roles($src_name, $object_type, $object_id);
     }
     if (!($otype_def = $this->scoper->data_sources->member_property($src_name, 'object_types', $object_type))) {
         return;
     }
     if (!$skip_user_validation && !$this->scoper_admin->user_can_admin_role($role_handle, $object_id, $src_name, $object_type)) {
         return;
     }
     // since we may be dumping a lot of hidden user <li> into the page, enumerate role names to shorten html
     $role_code = 'r' . array_search($role_handle, $this->role_handles);
     $role_def = $this->scoper->role_defs->get($role_handle);
     if (!isset($role_def->valid_scopes[OBJECT_SCOPE_RS])) {
         return;
     }
     if (empty($this->drew_objroles_marker)) {
         echo "<input type='hidden' name='rs_object_roles' value='true' />";
         $this->drew_objroles_marker = true;
     }
     // ========== OBJECT RESTRICTION CHECKBOX(ES) ============
     // checkbox to control object role scoping (dictates whether taxonomy and blog role assignments also be honored for operations on this object )
     $checked = empty($this->object_strict_roles[$role_handle]) ? '' : 'checked="checked"';
     $val = $checked ? '1' : '0';
     echo "<input type='hidden' name='last_objscope_{$role_code}' value='{$val}' id='last_objscope_{$role_code}' />";
     echo "\r\n<p style='margin-bottom:0.8em;'>" . "<span class='alignright'><a href='#wphead'>" . __('top', 'scoper') . '</a></span>' . "<label for='objscope_{$role_code}'>" . "<input type='checkbox' class='rs-check' name='objscope_{$role_code}' value='1' id='objscope_{$role_code}' {$checked} /> " . sprintf(__('Restrict for %1$s (<strong>only</strong> selected users/groups are %2$s)', 'scoper'), $otype_def->labels->singular_name, $this->scoper->role_defs->get_abbrev($role_handle, OBJECT_UI_RS)) . '</label></p>';
     if ($this->do_propagation_cboxes) {
         $checked = empty($this->child_strict_roles[$role_handle]) ? '' : 'checked="checked"';
         $val = $checked ? '1' : '0';
         echo "<input type='hidden' name='last_objscope_children_{$role_code}' value='{$val}' id='last_objscope_children_{$role_code}' />";
         echo "<p style='margin-top: 0.5em;'>" . "<label for='objscope_children_{$role_code}'>" . "<input type='checkbox' class='rs-check' name='objscope_children_{$role_code}' value='1' id='objscope_children_{$role_code}' {$checked} /> " . sprintf(__('Restrict for Sub-%1$s', 'scoper'), $otype_def->labels->name) . '</label></p>';
     }
     // ========== OBJECT ROLE ASSIGNMENT CHECKBOX(ES) ============
     // toggle groups / users view if both are enabled
     //echo "<p style='margin: 1em 0 0.2em 0;'><strong>" . sprintf(__('Assign %s Role:', 'scoper'), $display_name ) . '</strong></p>';
     //echo '<br />';
     $toggle_agents = USER_ROLES_RS && GROUP_ROLES_RS && !empty($this->all_groups);
     if ($toggle_agents) {
         if (!empty($this->current_roles[ROLE_BASIS_USER][$role_handle])) {
             $default_role_basis = ROLE_BASIS_USER;
         } else {
             $default_role_basis = ROLE_BASIS_GROUPS;
         }
         $class_selected = 'agp-selected_agent_colorized agp-selected_agent agp-agent';
         $class_unselected = 'agp-unselected_agent_colorized agp-unselected_agent agp-agent';
         $class = ROLE_BASIS_GROUPS == $default_role_basis ? "class='{$class_selected}'" : "class='{$class_unselected}'";
         $js_call = "agp_swap_display('{$role_code}_groups', '{$role_code}_user', '{$role_code}_show_group_roles', '{$role_code}_show_user_roles', '{$class_selected}', '{$class_unselected}')";
         $bottom_margin = !empty($GLOBALS['is_IE']) ? '-0.7em' : 0;
         echo "\r\n" . "<div class='agp_js_show' style='display:none;margin:0 0 {$bottom_margin} 0'>" . "<ul class='rs-list_horiz' style='margin-bottom:-0.1em'><li {$class}>" . "<a href='javascript:void(0)' id='{$role_code}_show_group_roles' onclick=\"{$js_call}\">" . __('Groups', 'scoper') . '</a></li>';
         $class = ROLE_BASIS_USER == $default_role_basis ? "class='{$class_selected}'" : "class='{$class_unselected}'";
         $js_call = "agp_swap_display('{$role_code}_user', '{$role_code}_groups', '{$role_code}_show_user_roles', '{$role_code}_show_group_roles', '{$class_selected}', '{$class_unselected}')";
         echo "\r\n" . "<li {$class}><a href='javascript:void(0)' id='{$role_code}_show_user_roles' onclick=\"{$js_call}\">" . __awp('Users') . '</a></li>' . '</ul></div>';
     }
     $class = "class='rs-agents'";
     //need effective line break here if not IE
     echo "<div style='clear:both;margin:0 0 0.3em 0' {$class}>";
     $role_ops = $this->scoper->cap_defs->get_cap_ops($this->scoper->role_defs->role_caps[$role_handle]);
     $agents_reqd_op = isset($role_ops[OP_EDIT_RS]) ? OP_EDIT_RS : OP_READ_RS;
     $containing_roles = $this->scoper->role_defs->get_containing_roles($role_handle);
     require_once dirname(__FILE__) . '/agents_checklist_rs.php';
     $args = array('suppress_extra_prefix' => true, 'default_hide_threshold' => 20, 'propagation' => $this->do_propagation_cboxes, 'otype_label_singular' => $otype_def->labels->singular_name, 'otype_label' => $otype_def->labels->name, 'object_type' => $object_type, 'object_id' => $object_id);
     $args['via_other_role_ids'] = array();
     // must set this here b/c subsequent for loop is set up for users iteration to recall via_other_role_ids from groups iteration
     foreach ($this->agent_captions as $role_basis => $agent_caption) {
         if (!is_array($this->blog_term_roles[$role_basis][$role_handle])) {
             $this->blog_term_roles[$role_basis][$role_handle] = array();
         }
         // for the purpose of indicating implicit role ownership, we will consider any assignment of a containing role as equivalent
         foreach (array_keys($containing_roles) as $containing_role_handle) {
             if (isset($this->blog_term_roles[$role_basis][$containing_role_handle]) && is_array($this->blog_term_roles[$role_basis][$containing_role_handle])) {
                 $this->blog_term_roles[$role_basis][$role_handle] = array_merge($this->blog_term_roles[$role_basis][$role_handle], $this->blog_term_roles[$role_basis][$containing_role_handle]);
             }
         }
         $this->blog_term_roles[$role_basis][$role_handle] = array_unique($this->blog_term_roles[$role_basis][$role_handle]);
         $hide_class = $toggle_agents && $role_basis != $default_role_basis ? ' class="agp_js_hide"' : '';
         echo "\r\n<div id='{$role_code}_{$role_basis}' {$hide_class}>";
         // also abbreviate "groups" to 'g', 'user' to 'u'
         $id_prefix = $role_code . substr($role_basis, 0, 1);
         if ($this->indicate_blended_roles && $object_id && GROUP_ROLES_RS && ROLE_BASIS_USER == $role_basis) {
             $args['via_other_basis_ids'] = array();
             // note users who are in a group that has this role object-assigned
             if (!empty($this->current_roles[ROLE_BASIS_GROUPS][$role_handle]['assigned'])) {
                 foreach (array_keys($this->current_roles[ROLE_BASIS_GROUPS][$role_handle]['assigned']) as $group_id) {
                     if (!isset($this->group_members[$group_id])) {
                         $this->group_members[$group_id] = ScoperAdminLib::get_group_members($group_id, COL_ID_RS, true);
                     }
                     //arg: maybe WP role metagroup
                     $args['via_other_basis_ids'] = array_merge($args['via_other_basis_ids'], $this->group_members[$group_id]);
                 }
             }
             // note users who are in a group that has this role term-assigned or blog-assigned (and not restricted)
             foreach ($this->blog_term_roles[ROLE_BASIS_GROUPS][$role_handle] as $group_id) {
                 if (!isset($this->group_members[$group_id])) {
                     $this->group_members[$group_id] = ScoperAdminLib::get_group_members($group_id, COL_ID_RS, true);
                 }
                 //arg: maybe WP role metagroup
                 $args['via_other_basis_ids'] = array_merge($args['via_other_basis_ids'], $this->group_members[$group_id]);
             }
             // note users who are in a group that has a containing role object-assigned
             // (note: via_other_role_ids element was set in previous iteration since ROLE_BASIS_GROUPS is first element in agents_caption array
             foreach ($args['via_other_role_ids'] as $group_id) {
                 if (!isset($this->group_members[$group_id])) {
                     $this->group_members[$group_id] = ScoperAdminLib::get_group_members($group_id, COL_ID_RS, true);
                 }
                 //arg: maybe WP role metagroup
                 $args['via_other_basis_ids'] = array_merge($args['via_other_basis_ids'], $this->group_members[$group_id]);
             }
             $args['via_other_basis_ids'] = array_unique($args['via_other_basis_ids']);
         }
         if ($this->indicate_blended_roles) {
             $args['via_other_scope_ids'] = $this->blog_term_roles[$role_basis][$role_handle];
         }
         $args['via_other_role_ids'] = array();
         if ($this->indicate_blended_roles && $containing_roles) {
             foreach (array_keys($containing_roles) as $containing_role_handle) {
                 if (isset($this->current_roles[$role_basis][$containing_role_handle]['assigned'])) {
                     $args['via_other_role_ids'] = array_merge($args['via_other_role_ids'], array_keys($this->current_roles[$role_basis][$containing_role_handle]['assigned']));
                 }
             }
             $args['via_other_role_ids'] = array_unique($args['via_other_role_ids']);
         }
         if ($object_id && $this->do_propagation_cboxes) {
             $args['for_entity_ids'] = isset($this->current_roles[$role_basis][$role_handle]['entity']) ? array_keys($this->current_roles[$role_basis][$role_handle]['entity']) : array();
             $args['for_children_ids'] = isset($this->current_roles[$role_basis][$role_handle]['children']) ? array_keys($this->current_roles[$role_basis][$role_handle]['children']) : '';
         }
         $args['eligible_ids'] = isset($this->eligible_agent_ids[$role_basis][$agents_reqd_op]) ? $this->eligible_agent_ids[$role_basis][$agents_reqd_op] : '';
         if ('post' == $src_name && 'auto-draft' == $object->post_status) {
             $args['suppress_last_agents'] = true;
         }
         if (!empty($this->current_roles[$role_basis][$role_handle]['assigned'])) {
             ScoperAgentsChecklist::agents_checklist($role_basis, $this->all_agents[$role_basis], $id_prefix, $this->current_roles[$role_basis][$role_handle]['assigned'], $args);
         } else {
             ScoperAgentsChecklist::agents_checklist($role_basis, $this->all_agents[$role_basis], $id_prefix, '', $args);
         }
         echo "\r\n</div>";
     }
     // end foreach role basis caption (user or group)
     echo '</div>';
     // class rs-agents
     //log_mem_usage_rs( 'end ItemRolesUI::draw_object_roles_content()' );
 }
    function touch_time($edit = 1, $for_post = 1, $tab_index = 0, $multi = 0, $id_prefix = '', $suppress_hidden_inputs = false, $suppress_current_inputs = false, $use_js = true, $empty_month_option = false)
    {
        global $wp_locale, $post, $comment;
        if ($for_post) {
            if (empty($post)) {
                $edit = true;
                $current_post_date = 0;
            } else {
                $edit = in_array($post->post_status, array('draft', 'pending')) && (!$post->post_date_gmt || '0000-00-00 00:00:00' == $post->post_date_gmt) ? false : true;
                $current_post_date = $post->post_date;
            }
        } else {
            $edit = true;
            $current_comment_date = empty($comment) ? 0 : $comment->comment_date;
        }
        $tab_index_attribute = '';
        if ((int) $tab_index > 0) {
            $tab_index_attribute = " tabindex='{$tab_index}'";
        }
        // echo '<label for="timestamp" style="display: block;"><input type="checkbox" class="checkbox" name="edit_date" value="1" id="timestamp"'.$tab_index_attribute.' /> '.__( 'Edit timestamp' ).'</label><br />';
        if (!empty($_POST)) {
            $jj = !empty($_POST[$id_prefix . 'jj']) ? $_POST[$id_prefix . 'jj'] : '';
            $mm = !empty($_POST[$id_prefix . 'mm']) ? $_POST[$id_prefix . 'mm'] : '';
            $aa = !empty($_POST[$id_prefix . 'aa']) ? $_POST[$id_prefix . 'aa'] : '';
            $hh = !empty($_POST[$id_prefix . 'hh']) ? $_POST[$id_prefix . 'hh'] : '';
            $mn = !empty($_POST[$id_prefix . 'mn']) ? $_POST[$id_prefix . 'mn'] : '';
            $ss = !empty($_POST[$id_prefix . 'ss']) ? $_POST[$id_prefix . 'ss'] : '';
        } else {
            $time_adj = time() + get_option('gmt_offset') * 3600;
            $post_date = $for_post ? $current_post_date : $current_comment_date;
            $jj = $edit ? mysql2date('d', $post_date, false) : gmdate('d', $time_adj);
            $mm = $edit ? mysql2date('m', $post_date, false) : gmdate('m', $time_adj);
            $aa = $edit ? mysql2date('Y', $post_date, false) : gmdate('Y', $time_adj);
            $hh = $edit ? mysql2date('H', $post_date, false) : gmdate('H', $time_adj);
            $mn = $edit ? mysql2date('i', $post_date, false) : gmdate('i', $time_adj);
            $ss = $edit ? mysql2date('s', $post_date, false) : gmdate('s', $time_adj);
        }
        if (!$suppress_current_inputs) {
            $cur_jj = gmdate('d', $time_adj);
            $cur_mm = gmdate('m', $time_adj);
            $cur_aa = gmdate('Y', $time_adj);
            $cur_hh = gmdate('H', $time_adj);
            $cur_mn = gmdate('i', $time_adj);
        }
        $month = "<select " . ($multi ? '' : "id='{$id_prefix}mm' ") . "name='{$id_prefix}mm' {$tab_index_attribute}>\n";
        if ($empty_month_option) {
            $month .= "\t\t\t" . '<option value=""></option>';
        }
        for ($i = 1; $i < 13; $i = $i + 1) {
            $month .= "\t\t\t" . '<option value="' . zeroise($i, 2) . '"';
            if ($i == $mm) {
                $month .= ' selected="selected"';
            }
            $month .= '>' . $wp_locale->get_month_abbrev($wp_locale->get_month($i)) . "</option>\n";
        }
        $month .= '</select>';
        $day = '<input type="text" ' . ($multi ? '' : 'id="' . $id_prefix . 'jj" ') . 'name="' . $id_prefix . 'jj" value="' . $jj . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" />';
        $year = '<input type="text" ' . ($multi ? '' : 'id="' . $id_prefix . 'aa" ') . 'name="' . $id_prefix . 'aa" value="' . $aa . '" size="4" maxlength="4"' . $tab_index_attribute . ' autocomplete="off" />';
        $hour = '<input type="text" ' . ($multi ? '' : 'id="' . $id_prefix . 'hh" ') . 'name="' . $id_prefix . 'hh" value="' . $hh . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" />';
        $minute = '<input type="text" ' . ($multi ? '' : 'id="' . $id_prefix . 'mn" ') . 'name="' . $id_prefix . 'mn" value="' . $mn . '" size="2" maxlength="2"' . $tab_index_attribute . ' autocomplete="off" />';
        /* translators: 1: month input, 2: day input, 3: year input, 4: hour input, 5: minute input */
        printf(__('%1$s%2$s, %3$s @ %4$s : %5$s'), $month, $day, $year, $hour, $minute);
        echo '<input type="hidden" id="' . $id_prefix . 'ss" name="' . $id_prefix . 'ss" value="' . $ss . '" />';
        if ($multi) {
            return;
        }
        echo "\n\n";
        foreach (array('mm', 'jj', 'aa', 'hh', 'mn') as $timeunit) {
            if (!$suppress_hidden_inputs) {
                echo '<input type="hidden" id="' . $id_prefix . 'hidden_' . $timeunit . '" name="' . $id_prefix . 'hidden_' . $timeunit . '" value="' . ${$timeunit} . '" />' . "\n";
            }
            if (!$suppress_current_inputs) {
                $cur_timeunit = 'cur_' . $timeunit;
                echo '<input type="hidden" id="' . $id_prefix . '' . $cur_timeunit . '" name="' . $id_prefix . $cur_timeunit . '" value="' . ${$cur_timeunit} . '" />' . "\n";
            }
        }
        ?>
		<p>
		<?php 
        if ($use_js) {
            ?>
		<a href="#<?php 
            echo $id_prefix;
            ?>
edit_timestamp" id="<?php 
            echo $id_prefix;
            ?>
save-timestamp" class="rs_role_save-timestamp hide-if-no-js button"><?php 
            echo __awp('OK');
            ?>
</a>
		<a href="#<?php 
            echo $id_prefix;
            ?>
edit_timestamp" id="<?php 
            echo $id_prefix;
            ?>
cancel-timestamp" class="rs_role_cancel-timestamp hide-if-no-js"><?php 
            echo __awp('Cancel');
            ?>
</a>
		<?php 
        } else {
            ?>
		<a href="#<?php 
            echo $id_prefix;
            ?>
edit_timestamp" id="<?php 
            echo $id_prefix;
            ?>
clear-timestamp" class="rs_role_clear-timestamp"><?php 
            echo __awp('Clear');
            ?>
</a>
		<?php 
        }
        ?>
		<?php 
        $checked = !empty($_POST["{$id_prefix}keep-timestamp"]) ? "checked='checked'" : '';
        ?>
		&nbsp;<input type="checkbox" id="<?php 
        echo $id_prefix;
        ?>
keep-timestamp" name="<?php 
        echo $id_prefix;
        ?>
keep-timestamp" <?php 
        echo $checked;
        ?>
 />&nbsp;<?php 
        _e('keep stored setting', 'scoper');
        ?>
		</p>
	<?php 
    }
function scoper_display_wp_roledefs($args = array())
{
    global $scoper;
    echo "<div id='wp-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('Note that only <strong>capabilities configured for filtering by Role Scoper</strong> are listed here.', 'scoper');
        echo ' ';
        _e('These WordPress role definitions may be modified via the Capability Manager or Role Manager plugin.', 'scoper');
        echo '</p>';
        echo '<p style="margin-top:0">';
        _e('To understand how your WordPress roles relate to type-specific RS Roles, see <a href="#wp_rs_equiv">WP/RS Role Equivalence</a>.', 'scoper');
        echo '</p>';
        echo '</div>';
    }
    $roles = $scoper->role_defs->get_matching('wp', '', '');
    echo '<h3>' . __('WordPress Roles', 'scoper'), '</h3>';
    ?>

<table class='widefat rs-backwhite'>
<thead>
<tr class="thead">
	<th width="15%"><?php 
    echo __awp('Role');
    ?>
</th>
	<th><?php 
    _e('Capabilities', 'scoper');
    ?>
</th>
</tr>
</thead>
<tbody>
<?php 
    $style = '';
    global $wp_roles;
    $wp_role_names = $wp_roles->role_names;
    uasort($wp_role_names, "strnatcasecmp");
    // sort by array values, but maintain keys
    // order WP roles by display name
    foreach (array_keys($wp_role_names) as $wp_role_name) {
        $role_handle = scoper_get_role_handle($wp_role_name, 'wp');
        $style = ' class="alternate"' == $style ? '' : ' class="alternate"';
        if (empty($scoper->role_defs->role_caps[$role_handle])) {
            continue;
        }
        $cap_names = array_keys($scoper->role_defs->role_caps[$role_handle]);
        sort($cap_names);
        $cap_display_names = array();
        foreach ($cap_names as $cap_name) {
            $cap_display_names[] = ucwords(str_replace('_', ' ', $cap_name));
        }
        $caplist = "<li>" . implode("</li><li>", $cap_display_names) . "</li>";
        echo "\n\t" . "<tr{$style}><td>" . $scoper->role_defs->get_display_name($role_handle) . "</td><td><ul class='rs-cap_list'>{$caplist}</ul></td></tr>";
    }
    // end foreach role
    echo '</tbody></table>';
    echo '<br /><br />';
    echo '<a name="wp_rs_equiv"></a>';
    echo '<h3>' . __('WP / RS Role Equivalence', 'scoper'), '</h3>';
    ?>

<table class='widefat rs-backwhite'>
<thead>
<tr class="thead">
	<th width="15%"><?php 
    _e('WP Role', 'scoper');
    ?>
</th>
	<th><?php 
    _e('Contained RS Roles', 'scoper');
    ?>
</th>
</tr>
</thead>
<tbody>
<?php 
    $style = '';
    $use_post_types = scoper_get_option('use_post_types');
    // order WP roles by display name
    foreach (array_keys($wp_role_names) as $wp_role_name) {
        $role_handle = scoper_get_role_handle($wp_role_name, 'wp');
        $style = ' class="alternate"' == $style ? '' : ' class="alternate"';
        $display_names = array();
        $contained_roles_handles = $scoper->role_defs->get_contained_roles($role_handle, false, 'rs');
        foreach (array_keys($contained_roles_handles) as $contained_role_handle) {
            $role_def = $scoper->role_defs->get($contained_role_handle);
            if ($role_def->object_type && post_type_exists($role_def->object_type) && !isset($use_post_types[$role_def->object_type])) {
                continue;
            }
            $display_names[] = $scoper->role_defs->get_display_name($contained_role_handle);
        }
        $list = "<li>" . implode("</li><li>", $display_names) . "</li>";
        $note = 'administrator' == $wp_role_name ? '<br /><br />' . __('<strong>note</strong>: Role Scoper also implicitly grants Administrators the Editor role for each enabled custom post type, and the Manager role for each enabled taxonomy.', 'scoper') : '';
        echo "\n\t" . "<tr{$style}><td>" . $scoper->role_defs->get_display_name($role_handle) . $note . "</td><td><ul class='rs-cap_list'>{$list}</ul></td></tr>";
    }
    // end foreach role
    echo '</tbody></table>';
    echo '<br /><br />';
    ?>

</div>

<?php 
}
Exemple #13
0
 function build_menu()
 {
     if (strpos($_SERVER['REQUEST_URI'], 'wp-admin/network/')) {
         return;
     }
     global $plugin_page_cr;
     if (!defined('USER_ROLES_RS') && isset($_POST['enable_group_roles'])) {
         scoper_use_posted_init_options();
     }
     global $current_user;
     $is_option_administrator = is_option_administrator_rs();
     $is_user_administrator = is_user_administrator_rs();
     $is_content_administrator = is_content_administrator_rs();
     /*
     // optional hack to prevent roles / restrictions menu for non-Administrators
     //
     // This is now handled as a Role Scoper Option.
     // In Roles > Options > Features > Content Maintenance, set "Roles and Restrictions can be set" to "Administrators only" 
     //
     // To prevent Role Scoper from filtering the backend at all, go to Roles > Options > Realm > Access Types and deselect "editing and administering content"
     //
     // end optional hack
     */
     $require_blogwide_editor = scoper_get_option('role_admin_blogwide_editor_only');
     if (!$is_content_administrator && 'admin_content' == $require_blogwide_editor) {
         if (!$is_option_administrator) {
             return;
         }
     }
     if (!$is_user_administrator && 'admin' == $require_blogwide_editor) {
         if (!$is_option_administrator) {
             return;
         }
     }
     $can_admin_objects = array();
     $can_admin_terms = array();
     $use_post_types = scoper_get_option('use_post_types');
     $use_taxonomies = scoper_get_option('use_taxonomies');
     // which object types does this user have any administration over?
     foreach ($this->scoper->data_sources->get_all() as $src_name => $src) {
         if (!empty($src->no_object_roles) || !empty($src->taxonomy_only) || 'group' == $src_name) {
             continue;
         }
         $object_types = isset($src->object_types) ? $src->object_types : array($src_name => true);
         foreach (array_keys($object_types) as $object_type) {
             if ('post' == $src_name && empty($use_post_types[$object_type])) {
                 continue;
             }
             if (is_administrator_rs($src, 'user') || $this->user_can_admin_object($src_name, $object_type, 0, true)) {
                 if (scoper_get_otype_option('use_object_roles', "{$src_name}:{$object_type}")) {
                     $can_admin_objects[$src_name][$object_type] = true;
                 }
             }
         }
     }
     // which taxonomies does this user have any administration over?
     foreach ($this->scoper->taxonomies->get_all() as $taxonomy => $tx) {
         if (taxonomy_exists($taxonomy) && empty($use_taxonomies[$taxonomy]) && 'post' == $tx->object_source) {
             continue;
         }
         if (is_taxonomy_used_rs($taxonomy) && (is_administrator_rs($tx->source, 'user') || $this->user_can_admin_terms($taxonomy))) {
             $can_admin_terms[$taxonomy] = true;
         }
     }
     // Users Tab
     if (DEFINE_GROUPS_RS) {
         $can_manage_groups = DEFINE_GROUPS_RS && ($is_user_administrator || current_user_can('recommend_group_membership'));
         $cap_req = $can_manage_groups ? 'read' : 'manage_groups';
         $groups_caption = defined('GROUPS_CAPTION_RS') ? GROUPS_CAPTION_RS : __('Role Groups', 'scoper');
         if (!IS_MU_RS || !scoper_get_site_option('mu_sitewide_groups')) {
             add_submenu_page('users.php', $groups_caption, $groups_caption, $cap_req, 'rs-groups', array(&$this, 'menu_handler'));
         } elseif (IS_MU_RS && !awp_ver('3.1')) {
             add_submenu_page("ms-admin.php", $groups_caption, $groups_caption, $cap_req, 'rs-groups', array(&$this, 'menu_handler'));
         }
         // satisfy WordPress' demand that all admin links be properly defined in menu
         if ('rs-default_groups' == $plugin_page_cr) {
             add_submenu_page('users.php', __('User Groups', 'scoper'), __('Default Groups', 'scoper'), $cap_req, 'rs-default_groups', array(&$this, 'menu_handler'));
         }
         if ('rs-group_members' == $plugin_page_cr) {
             add_submenu_page('users.php', __('User Groups', 'scoper'), __('Group Members', 'scoper'), $cap_req, 'rs-group_members', array(&$this, 'menu_handler'));
         }
     }
     // the rest of this function pertains to Roles and Restrictions menus
     if (!$is_user_administrator && !$can_admin_terms && !$is_user_administrator && !$can_admin_objects) {
         return;
     }
     $general_roles = $is_user_administrator;
     // && scoper_get_option('rs_blog_roles');  // rs_blog_roles option has never been active in any RS release; leave commented here in case need arises
     // determine the official WP-registered URL for roles and restrictions menus
     $object_submenus_first = false;
     $use_users_menu = defined('OZH_MENU_VER') && !defined('SCOPER_FORCE_ROLES_MENU') || defined('SCOPER_FORCE_USERS_MENU');
     $tweak_menu = false;
     if ($use_users_menu) {
         $roles_menu = 'users.php';
         $restrictions_menu = 'users.php';
         if ($is_option_administrator) {
             add_submenu_page($roles_menu, __('Role Options', 'scoper'), __('Role Options', 'scoper'), 'read', 'rs-options', array(&$this, 'menu_handler'));
         }
     } else {
         if (!empty($can_admin_terms['category'])) {
             $roles_menu = 'rs-category-roles_t';
             $restrictions_menu = 'rs-category-restrictions_t';
         } elseif (!empty($can_admin_objects['post']['post'])) {
             $roles_menu = 'rs-post-roles';
             $restrictions_menu = 'rs-post-restrictions';
             $object_submenus_first = true;
         } elseif (!empty($can_admin_objects['post']['page'])) {
             // TODO: handle custom types here?
             $roles_menu = 'rs-page-roles';
             $restrictions_menu = 'rs-page-restrictions';
             $object_submenus_first = true;
         } elseif ($can_admin_terms && $this->scoper->taxonomies->member_property(key($can_admin_terms), 'requires_term')) {
             $taxonomy = key($can_admin_terms);
             $roles_menu = "rs-{$taxonomy}-roles_t";
             $restrictions_menu = "rs-{$taxonomy}-restrictions_t";
         } elseif ($can_admin_objects) {
             $src_name = key($can_admin_objects);
             $object_type = key($can_admin_objects[$src_name]);
             if ($src_name != $object_type && 'post' != $src_name) {
                 $roles_menu = "rs-{$object_type}-roles_{$src_name}";
                 $restrictions_menu = "rs-{$object_type}-restrictions_{$src_name}";
             } else {
                 $roles_menu = "rs-{$object_type}-roles";
                 $restrictions_menu = "rs-{$object_type}-restrictions";
             }
             $object_submenus_first = true;
         } else {
             // shouldn't ever need this
             $roles_menu = 'rs-roles-post';
             $restrictions_menu = 'rs-restrictions-post';
             $object_submenus_first = true;
         }
         if ($general_roles) {
             $roles_menu = 'rs-general_roles';
         }
         if ($is_option_administrator) {
             $roles_menu = 'rs-options';
         }
         // option administrators always have RS Options as top level roles submenu
         if ($is_user_administrator) {
             if (empty($restrictions_menu)) {
                 $restrictions_menu = 'rs-category-restrictions_t';
             }
             // If RS Realms are customized, the can_admin_terms / can_admin_objects result can override this default, even for user administrators
         }
         // Register the menus with WP using URI and links determined above
         global $menu;
         //  Manually set menu indexes for positioning below Users menu,
         //  but not if Flutter (a.k.a. Fresh Page) plugin is active.  It re-indexes menu items
         if (!defined('SCOPER_DISABLE_MENU_TWEAK')) {
             //if ( awp_ver('2.9') ) {
             // review each WP version for menu indexes until there's a clean way to force menu proximity to 'Users'
             if (isset($menu[70]) && $menu[70][2] == 'users.php') {
                 // WP 2.9 and 3.0
                 $tweak_menu = true;
                 $restrictions_menu_key = 71;
                 $roles_menu_key = 72;
             }
             //}
         }
         $roles_cap = 'read';
         // we apply other checks within this function to confirm the menu is valid for current user
         $restrictions_caption = __('Restrictions', 'scoper');
         $roles_caption = __('Roles', 'scoper');
         if ($tweak_menu) {
             add_menu_page($restrictions_caption, __('Restrictions', 'scoper'), 'read', $restrictions_menu, array(&$this, 'menu_handler'), SCOPER_URLPATH . '/admin/images/menu/restrictions.png', $restrictions_menu_key);
             add_menu_page($roles_caption, __('Roles', 'scoper'), $roles_cap, $roles_menu, array(&$this, 'menu_handler'), SCOPER_URLPATH . '/admin/images/menu/roles.png', $roles_menu_key);
         } else {
             add_menu_page($restrictions_caption, __('Restrictions', 'scoper'), 'read', $restrictions_menu, array(&$this, 'menu_handler'), SCOPER_URLPATH . '/admin/images/menu/restrictions.png');
             add_menu_page($roles_caption, __('Roles', 'scoper'), $roles_cap, $roles_menu, array(&$this, 'menu_handler'), SCOPER_URLPATH . '/admin/images/menu/roles.png');
         }
     }
     // endif putting roles and restrictions links in Users menu
     if ($general_roles) {
         $menu_label = $use_users_menu ? __('General Roles', 'scoper') : __('General', 'scoper');
         add_submenu_page($roles_menu, __('General Roles', 'scoper'), $menu_label, 'read', 'rs-general_roles', array(&$this, 'menu_handler'));
     }
     $first_pass = true;
     $submenu_types = $object_submenus_first ? array('object', 'term') : array('term', 'object');
     foreach ($submenu_types as $scope) {
         if ('term' == $scope) {
             // Term Roles and Restrictions (will only display objects user can edit)
             if ($can_admin_terms) {
                 // Will only allow assignment to terms for which current user has admin cap
                 // Term Roles page also prevents assignment or removal of roles current user doesn't have
                 foreach ($this->scoper->taxonomies->get_all() as $taxonomy => $tx) {
                     if (empty($can_admin_terms[$taxonomy])) {
                         continue;
                     }
                     $show_roles_menu = true;
                     $menu_label = $use_users_menu ? sprintf(__('%s Roles', 'scoper'), $tx->labels->singular_name) : $tx->labels->name;
                     add_submenu_page($roles_menu, sprintf(__('%s Roles', 'scoper'), $tx->labels->singular_name), $menu_label, 'read', "rs-{$taxonomy}-roles_t", array(&$this, 'menu_handler'));
                     if (!empty($tx->requires_term)) {
                         $show_restrictions_menu = true;
                         $menu_label = $use_users_menu ? sprintf(__('%s Restrictions', 'scoper'), $tx->labels->singular_name) : $tx->labels->name;
                         add_submenu_page($restrictions_menu, sprintf(__('%s Restrictions', 'scoper'), $tx->labels->singular_name), $menu_label, 'read', "rs-{$taxonomy}-restrictions_t", array(&$this, 'menu_handler'));
                     }
                 }
                 // end foreach taxonomy
             }
             // endif can admin terms
         } else {
             // Object Roles (will only display objects user can edit)
             if ($can_admin_objects) {
                 foreach ($this->scoper->data_sources->get_all() as $src_name => $src) {
                     if (!empty($src->no_object_roles) || !empty($src->taxonomy_only) || 'group' == $src_name) {
                         continue;
                     }
                     $object_types = isset($src->object_types) ? $src->object_types : array($src_name => true);
                     foreach (array_keys($object_types) as $object_type) {
                         if (empty($can_admin_objects[$src_name][$object_type])) {
                             continue;
                         }
                         if ($require_blogwide_editor) {
                             if (!$this->scoper->user_can_edit_blogwide($src_name, $object_type, array('require_others_cap' => true))) {
                                 continue;
                             }
                         }
                         $show_roles_menu = true;
                         $show_restrictions_menu = true;
                         if ($src_name != $object_type && 'post' != $src_name) {
                             $roles_page = "rs-{$object_type}-roles_{$src_name}";
                             $restrictions_page = "rs-{$object_type}-restrictions_{$src_name}";
                         } else {
                             $roles_page = "rs-{$object_type}-roles";
                             $restrictions_page = "rs-{$object_type}-restrictions";
                         }
                         $src_otype = isset($src->object_types) ? "{$src_name}:{$object_type}" : $src_name;
                         $item_label_singular = $this->interpret_src_otype($src_otype, 'singular_name');
                         $item_label = $this->interpret_src_otype($src_otype);
                         $menu_label = $use_users_menu ? sprintf(__('%s Roles', 'scoper'), $item_label_singular) : $item_label;
                         add_submenu_page($roles_menu, sprintf(__('%s Roles', 'scoper'), $item_label_singular), $menu_label, 'read', $roles_page, array(&$this, 'menu_handler'));
                         $menu_label = $use_users_menu ? sprintf(__('%s Restrictions', 'scoper'), $item_label_singular) : $item_label;
                         add_submenu_page($restrictions_menu, sprintf(__('%s Restrictions', 'scoper'), $item_label_singular), $menu_label, 'read', $restrictions_page, array(&$this, 'menu_handler'));
                     }
                     // end foreach obj type
                 }
                 // end foreach data source
             }
             // endif can admin objects
         }
         // endif drawing object scope submenus
     }
     // end foreach submenu scope
     if ($is_user_administrator) {
         add_submenu_page($roles_menu, __('About Role Scoper', 'scoper'), __('About', 'scoper'), 'read', 'rs-about', array(&$this, 'menu_handler'));
     }
     global $submenu;
     // Change Role Scoper Options submenu title from default "Roles" to "Options"
     if ($is_option_administrator) {
         if (isset($submenu[$roles_menu][0][2]) && $roles_menu == $submenu[$roles_menu][0][2]) {
             $submenu[$roles_menu][0][0] = __awp('Options');
         }
         // satisfy WordPress' demand that all admin links be properly defined in menu
         if ('rs-attachments_utility' == $plugin_page_cr) {
             add_submenu_page($roles_menu, __('Attachment Utility', 'scoper'), __('Attachment Utility', 'scoper'), 'read', 'rs-attachments_utility', array(&$this, 'menu_handler'));
         }
     } elseif (empty($show_restrictions_menu) || empty($show_roles_menu)) {
         // Remove Roles or Restrictions menu if it has no submenu
         if ($tweak_menu) {
             // since we forced the menu keys, no need to loop through menu looking for them
             if (empty($show_restrictions_menu) && isset($menu[$restrictions_menu_key])) {
                 unset($menu[$restrictions_menu_key]);
             }
             if (empty($show_roles_menu) && isset($menu[$roles_menu_key])) {
                 unset($menu[$roles_menu_key]);
             }
         } else {
             global $menu;
             foreach (array_keys($menu) as $key) {
                 if (isset($menu[$key][0])) {
                     if (empty($show_roles_menu) && $roles_caption == $menu[$key][0]) {
                         unset($menu[$key]);
                     } elseif (empty($show_restrictions_menu) && $restrictions_caption == $menu[$key][0]) {
                         unset($menu[$key]);
                     }
                 }
             }
         }
     }
     // WP MU site options
     if (!awp_ver('3.1') && $is_option_administrator && IS_MU_RS) {
         scoper_mu_site_menu();
     }
     // satisfy WordPress' demand that all admin links be properly defined in menu
     if ('rs-object_role_edit' == $plugin_page_cr) {
         add_submenu_page($roles_menu, __('Object Role Edit', 'scoper'), __('Object Role Edit', 'scoper'), 'read', 'rs-object_role_edit', array(&$this, 'menu_handler'));
     }
 }
<?php

if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME'])) {
    die('This page cannot be called directly.');
}
if (!is_option_administrator_rs()) {
    wp_die(__awp('Cheatin&#8217; uh?'));
}
function scoper_attach_linked_uploads($echo = false)
{
    global $wpdb;
    require_once SCOPER_ABSPATH . '/uploads_rs.php';
    if (MULTISITE) {
        global $wpdb, $blog_id;
        $blog_ids = scoper_get_col("SELECT blog_id FROM {$wpdb->blogs} ORDER BY blog_id");
        $orig_blog_id = $blog_id;
    } else {
        $blog_ids = array('1');
    }
    foreach ($blog_ids as $id) {
        if (count($blog_ids) > 1) {
            switch_to_blog($id);
            _e("<br /><strong>site {$id} :</strong><br />");
        }
        $uploads = scoper_get_upload_info();
        $site_url = untrailingslashit(get_option('siteurl'));
        if (false === strpos($uploads['baseurl'], $site_url)) {
            if ($echo) {
                _e('<strong>Note</strong>: Direct access to uploaded file attachments cannot be filtered because your WP_CONTENT_DIR is not in the WordPress branch.', 'scoper');
                echo '<br /><br />';
                _e('The operation was terminated due to an invalid configuration.', 'scoper');
function scoper_new_version_notice()
{
    $rechecked = false;
    $check_minutes = scoper_get_option('version_check_minutes');
    $last_check = scoper_get_option('last_version_update_check');
    if (time() - $last_check > $check_minutes * 60 || !($vcheck = get_site_option('scoper_version_info'))) {
        $vcheck = wp_remote_fopen('http://agapetry.net/downloads/role-scoper_version.chk');
        $rechecked = true;
        update_option('scoper_version_info', $vcheck);
    }
    if ($vcheck) {
        if (time() - $last_check > $check_minutes * 60 || !($vcheck_ext = get_site_option('scoper_extension_info'))) {
            $vcheck_ext = awp_remote_fopen('http://agapetry.net/downloads/role-scoper-extensions.chk', 5);
            $rechecked = true;
            update_option('scoper_extension_info', $vcheck_ext);
        }
    } else {
        $vcheck_ext = false;
    }
    if ($rechecked) {
        update_option('scoper_last_version_update_check', time());
    }
    if ($vcheck) {
        $status = explode('@', $vcheck);
        $theVersion = $status[1];
        if (version_compare(strval($theVersion), strval(SCOPER_VERSION), '>') == 1) {
            $msg = '<strong>' . sprintf(__("A new version of Role Scoper is available (%s)", "scoper"), $theVersion);
            if ($rechecked || !($vcheck = get_site_option('scoper_version_message'))) {
                $vcheck = awp_remote_fopen('http://agapetry.net/downloads/role-scoper.chk', 5);
                add_site_option('scoper_version_message', $vcheck);
            }
            if ($vcheck) {
                $status = explode('@', $vcheck);
                $theMessage = $status[3];
                if ($ver_pos = strpos($theMessage, '<br />' . SCOPER_VERSION)) {
                    $theMessage = substr($theMessage, 0, $ver_pos);
                }
                $theMessage = str_replace("'", '&#39;', $theMessage);
                // Despite this precaution, don't include apostrophes in .chk file because older RS versions (< 1.0.0-rc9) will choke on it.
                $theMessage = str_replace('"', '&quot;', $theMessage);
                $msg .= '</strong><small>' . $theMessage . '</small>';
            }
            if (strpos($msg, '<!--more-->')) {
                $more_caption = __('read more...', 'scoper');
                $msg = preg_replace('/\\<\\!\\-\\-more\\-\\-\\>/', '<a href="javascript:void(0)" onclick="rs_display_version_more();">' . $more_caption . '</a><p id="rs_version_more" class="rs_more" style="display:none;">', $msg, 1);
                $msg .= '</p>';
            } else {
                $msg .= '<br />';
            }
            $msg .= '<a href="http://agapetry.net/category/role-scoper/" target="_blank">' . __('Read about the update', 'scoper') . '</a>';
            $msg .= '&nbsp;&nbsp;&nbsp;<a href="http://wordpress.org/extend/plugins/role-scoper/changelog/" target="_blank">' . __('View full changelog', 'scoper') . '</a>';
            if (version_compare(strval($theVersion), '1.0.0', '>=')) {
                $url = awp_plugin_update_url(SCOPER_BASENAME);
                $msg .= '&nbsp;&nbsp;&nbsp;<a href="' . $url . '">' . __awp('Upgrade Automatically') . '</a>';
            } else {
                $msg .= '&nbsp;&nbsp;&nbsp;<a href="http://agapetry.net/downloads/role-scoper_current" target="_blank">' . __('Download for manual install', 'scoper') . '</a>';
            }
            // slick method copied from NextGEN Gallery plugin
            add_action('admin_notices', create_function('', 'echo \'<div id="rs-ver_msg" class="plugin-update rs-ver_msg fade" style="margin:0;"><p>' . $msg . '</p></div>\';'));
        }
    }
    if ($vcheck_ext) {
        $plugin_titles = array();
        $plugin_links = array();
        if ($extensions = explode(';', $vcheck_ext)) {
            foreach ($extensions as $ext) {
                if ($ext_info = explode(',', $ext)) {
                    if (count($ext_info) < 4) {
                        continue;
                    }
                    if (($plugin_file = awp_is_plugin_active($ext_info[0])) && !awp_is_plugin_active($ext_info[1])) {
                        $plugin_path = WP_CONTENT_DIR . '/plugins/' . $plugin_file;
                        if (file_exists($plugin_path)) {
                            $plugin_data = implode('', file($plugin_path));
                            preg_match('|Plugin Name:(.*)$|mi', $plugin_data, $name);
                            if ($name) {
                                $name = trim($name[1]);
                                $plugin_titles[$ext_info[0]] = $name;
                                if (false === strpos($ext_info[3], 'wp_repository') || false !== strpos($ext_info[3], 'is_alpha')) {
                                    $plugin_links[$ext_info[0]] = "http://agapetry.net/category/role-scoper-extensions/";
                                } else {
                                    $plugin_links[$ext_info[0]] = awp_plugin_info_url($ext_info[2]);
                                }
                            }
                        }
                    }
                }
            }
            $plugins = get_option('active_plugins');
            if ($plugin_titles) {
                $plugin_array = array();
                foreach ($plugin_titles as $name => $title) {
                    $plugin_array[] = "<a href=\"{$plugin_links[$name]}\">{$title}</a>";
                }
                $msg = '<strong>' . sprintf(__("Role Scoper Extensions are available for the following plugins: %s", "scoper"), implode(', ', $plugin_array)) . '</strong><br />';
                // slick method copied from NextGEN Gallery plugin
                add_action('admin_notices', create_function('', 'echo \'<div id="rs-ext_ver_msg" class="plugin-update rs-ver_msg fade"><p>' . $msg . '</p></div>\';'));
            }
        }
    }
}
            continue;
        }
        echo "<br /><h4><a name='{$object_type}'></a><strong>";
        printf(__('Modify role assignments for %s', 'scoper'), $otype->labels->name);
        echo '</strong></h4>';
        //display each role eligible for group/user assignment
        $row_class = 'rs-backwhite';
        ?>

<ul class="rs-termlist" style="padding-left:0.1em;"><li>
<table class='widefat'>
<thead>
<tr class="thead">
	<th class="rs-tightcol"></th>
	<th class="rs-tightcol"><?php 
        echo __awp('Role');
        ?>
</th>
	<th><?php 
        echo $agent_caption_plural;
        ?>
</th>
</tr>
</thead>
<tbody>
<?php 
        foreach ($otype_roles as $object_type => $roles) {
            foreach ($roles as $role_handle => $role) {
                if (!empty($role->anon_only)) {
                    continue;
                }
        do_action('edit_group_profile_rs', $group_id);
        ?>
</div>

<?php 
    }
    // current user is a group administrator (otherwise we suppress Administrators, Moderators and Group Roles UI)
    ?>


<?php 
    if ('edit' == $mode) {
        ?>
<a href="javascript:void(0)" class="button" style="padding:0.35em; margin-right: 1em;" onclick="javascript:location.href='admin.php?page=rs-groups&amp;cancel=1'">
<?php 
        echo __awp('Cancel');
        ?>
</a>
<?php 
    }
    ?>

<span class="submit" style='border:none;'>
<input type="submit" value="<?php 
    echo $submitName;
    ?>
"/>
</span>

</fieldset>
 function display_ui_user_roles($user, $groups_only = false)
 {
     global $scoper;
     $blog_roles = array();
     $term_roles = array();
     $blog_roles = $user->get_blog_roles_daterange('rs', array('include_role_duration_key' => true, 'enforce_duration_limits' => false));
     // arg: return array with additional key dimension for role duration
     // for Administrators, display any custom post General Roles which were auto-assigned to maintain default editing rights
     global $current_rs_user;
     if ($current_rs_user->ID == $user->ID) {
         if (is_content_administrator_rs()) {
             $blog_roles[''][''] = isset($blog_roles['']['']) ? array_merge($current_rs_user->assigned_blog_roles['']) : $current_rs_user->assigned_blog_roles[''];
         }
     }
     foreach ($this->scoper->taxonomies->get_all() as $taxonomy => $tx) {
         $term_roles[$taxonomy] = $user->get_term_roles_daterange($taxonomy, 'rs', array('include_role_duration_key' => true, 'enforce_duration_limits' => false));
     }
     // arg: return array with additional key dimension for role duration
     $duration_limits_enabled = scoper_get_option('role_duration_limits');
     $content_date_limits_enabled = scoper_get_option('role_content_date_limits');
     $html = '';
     if ($groups_only) {
         if (IS_MU_RS && scoper_get_option('mu_sitewide_groups', true)) {
             global $blog_id;
             $list = scoper_get_blog_list(0, 'all');
             $blog_path = '';
             foreach ($list as $blog) {
                 if ($blog['blog_id'] == $blog_id) {
                     $blog_path = $blog['path'];
                     break;
                 }
             }
             $group_caption = sprintf(__('Group Roles %1$s(for %2$s)%3$s', 'scoper'), '<span style="font-weight: normal">', rtrim($blog_path, '/'), '</span>');
         } else {
             $group_caption = __('Group Roles', 'scoper');
         }
     } else {
         $html .= "<div id='userprofile_rolesdiv_rs' class='rs-scoped_role_profile'>";
         $html .= "<h3>" . __('Scoped Roles', 'scoper') . "</h3>";
         $wp_blog_roles = array_intersect_key($user->assigned_blog_roles[''], $scoper->role_defs->get_matching('wp'));
         if (!empty($wp_blog_roles)) {
             $display_names = array();
             foreach (array_keys($wp_blog_roles) as $role_handle) {
                 $display_names[] = $scoper->role_defs->get_display_name($role_handle);
             }
             $html .= sprintf(__("<strong>Assigned WordPress Role:</strong> %s", 'scoper'), implode(", ", $display_names));
             if ($contained_roles = $this->scoper->role_defs->get_contained_roles(array_keys($wp_blog_roles), false, 'rs')) {
                 $display_names = array();
                 foreach (array_keys($contained_roles) as $role_handle) {
                     $display_names[] = $this->scoper->role_defs->get_display_name($role_handle);
                 }
                 $html .= '<br /><span class="rs-gray">';
                 $html .= sprintf(__("(contains %s)", 'scoper'), implode(", ", $display_names));
                 $html .= '</span>';
             }
         }
         $html .= '<br /><br />';
     }
     $display_names = array();
     foreach (array_keys($blog_roles) as $duration_key) {
         if (is_serialized($duration_key)) {
             $role_date_limits = unserialize($duration_key);
             $role_date_limits->date_limited = true;
         } else {
             $role_date_limits = array();
         }
         foreach (array_keys($blog_roles[$duration_key]) as $date_key) {
             $display_names = array();
             if (is_serialized($date_key)) {
                 $content_date_limits = unserialize($date_key);
                 $content_date_limits->content_date_limited = true;
             } else {
                 $content_date_limits = array();
             }
             $date_caption = '';
             if ($role_date_limits || $content_date_limits) {
                 $limit_class = '';
                 // unused byref arg
                 $limit_style = '';
                 // unused byref arg
                 $link_class = '';
                 // unused byref arg
                 ScoperAdminUI::set_agent_formatting(array_merge((array) $role_date_limits, (array) $content_date_limits), $date_caption, $limit_class, $link_class, $limit_style, false);
                 // arg: no title='' wrapper around date_caption
                 $date_caption = '<span class="rs-gray"> ' . trim($date_caption) . '</span>';
             }
             if ($rs_blog_roles = $this->scoper->role_defs->filter($blog_roles[$duration_key][$date_key], array('role_type' => 'rs'))) {
                 foreach (array_keys($rs_blog_roles) as $role_handle) {
                     $display_names[] = $this->scoper->role_defs->get_display_name($role_handle);
                 }
                 $url = "admin.php?page=rs-general_roles";
                 $linkopen = "<strong><a href='{$url}'>";
                 $linkclose = "</a></strong>";
                 $list = implode(", ", $display_names);
                 if ($groups_only) {
                     $html .= sprintf(_n('<strong>%1$sGeneral Role%2$s</strong>%4$s: %3$s', '<strong>%1$sGeneral Roles%2$s</strong>%4$s: %3$s', count($display_names), 'scoper'), $linkopen, $linkclose, $list, $date_caption);
                 } else {
                     $html .= sprintf(_n('<strong>Additional %1$sGeneral Role%2$s</strong>%4$s: %3$s', '<strong>Additional %1$sGeneral Roles%2$s</strong>%4$s: %3$s', count($display_names), 'scoper'), $linkopen, $linkclose, $list, $date_caption);
                 }
                 if ($contained_roles = $this->scoper->role_defs->get_contained_roles(array_keys($rs_blog_roles), false, 'rs')) {
                     $display_names = array();
                     foreach (array_keys($contained_roles) as $role_handle) {
                         $display_names[] = $this->scoper->role_defs->get_display_name($role_handle);
                     }
                     $html .= '<br /><span class="rs-gray">';
                     $html .= sprintf(__("(contains %s)", 'scoper'), implode(", ", $display_names));
                     $html .= '</span>';
                 }
                 $html .= '<br /><br />';
             }
         }
         // end foreach content date range
     }
     // end foreach role duration date range
     $disable_role_admin = false;
     global $profileuser;
     $viewing_own_profile = !empty($profileuser) && $profileuser->ID == $current_rs_user->ID;
     if (!$viewing_own_profile) {
         if ($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;
             }
             $disable_role_admin = !$scoper->user_can_edit_blogwide('post', '', array('require_others_cap' => true, 'status' => 'publish'));
         }
     }
     foreach ($this->scoper->taxonomies->get_all() as $taxonomy => $tx) {
         if (empty($term_roles[$taxonomy])) {
             continue;
         }
         $val = ORDERBY_HIERARCHY_RS;
         $args = array('order_by' => $val);
         if (!($terms = $this->scoper->get_terms($taxonomy, UNFILTERED_RS, COLS_ALL_RS, 0, $args))) {
             continue;
         }
         $object_types = array();
         $obj_src = $this->scoper->data_sources->get($tx->object_source);
         if (!$obj_src || !is_array($obj_src->object_types)) {
             continue;
         }
         foreach (array_keys($obj_src->object_types) as $object_type) {
             if (scoper_get_otype_option('use_term_roles', $tx->object_source, $object_type)) {
                 $object_types[] = $object_type;
             }
         }
         if (!$object_types) {
             continue;
         }
         $object_types[] = $taxonomy;
         $admin_terms = $disable_role_admin ? array() : $this->scoper->get_terms($taxonomy, ADMIN_TERMS_FILTER_RS, COL_ID_RS);
         $strict_terms = $this->scoper->get_restrictions(TERM_SCOPE_RS, $taxonomy);
         $role_defs = $this->scoper->role_defs->get_matching('rs', $tx->object_source, $object_types);
         $tx_src = $this->scoper->data_sources->get($tx->source);
         $col_id = $tx_src->cols->id;
         $col_name = $tx_src->cols->name;
         $term_names = array();
         foreach ($terms as $term) {
             $term_names[$term->{$col_id}] = $term->{$col_name};
         }
         foreach (array_keys($term_roles[$taxonomy]) as $duration_key) {
             if (is_serialized($duration_key)) {
                 $role_date_limits = unserialize($duration_key);
                 $role_date_limits->date_limited = true;
             } else {
                 $role_date_limits = array();
             }
             foreach (array_keys($term_roles[$taxonomy][$duration_key]) as $date_key) {
                 if (is_serialized($date_key)) {
                     $content_date_limits = unserialize($date_key);
                     $content_date_limits->content_date_limited = true;
                 } else {
                     $content_date_limits = array();
                 }
                 $title = '';
                 $date_caption = '';
                 $limit_class = '';
                 $limit_style = '';
                 $link_class = '';
                 $style = '';
                 if ($role_date_limits || $content_date_limits) {
                     ScoperAdminUI::set_agent_formatting(array_merge((array) $role_date_limits, (array) $content_date_limits), $date_caption, $limit_class, $link_class, $limit_style);
                     $title = "title='{$date_caption}'";
                     $date_caption = '<span class="rs-gray"> ' . trim($date_caption) . '</span>';
                 }
                 if ($admin_terms) {
                     $url = "admin.php?page=rs-{$taxonomy}-roles_t";
                     //$html .= ("\n<h4><a href='$url'>" . sprintf(_ x('%1$s Roles%2$s:', 'Category Roles, content date range', 'scoper'), $tx->display_name, '</a><span style="font-weight:normal">' . $date_caption) . '</span></h4>' );
                     $html .= "\n<h4><a href='{$url}'>" . sprintf(__('%1$s Roles%2$s:', 'scoper'), $tx->labels->singular_name, '</a><span style="font-weight:normal">' . $date_caption) . '</span></h4>';
                 } else {
                     $html .= "\n<h4>" . sprintf(__('%1$s Roles%2$s:', 'scoper'), $tx->labels->singular_name, $date_caption) . '</h4>';
                 }
                 //$html .= ("\n<h4>" . sprintf(_ x('%1$s Roles%2$s:', 'Category Roles, content date range', 'scoper'), $tx->display_name, $date_caption) . '</h4>' );
                 $html .= '<ul class="rs-termlist" style="padding-left:0.1em;">';
                 $html .= '<li>';
                 $html .= '<table class="widefat"><thead><tr class="thead">';
                 $html .= '<th class="rs-tightcol">' . __awp('Role') . '</th>';
                 $html .= '<th>' . $tx->labels->name . '</th>';
                 $html .= '</tr></thead><tbody>';
                 foreach (array_keys($role_defs) as $role_handle) {
                     if (isset($term_roles[$taxonomy][$duration_key][$date_key][$role_handle])) {
                         $role_terms = $term_roles[$taxonomy][$duration_key][$date_key][$role_handle];
                         $role_display = $this->scoper->role_defs->get_display_name($role_handle);
                         $term_role_list = array();
                         foreach ($role_terms as $term_id) {
                             if (!in_array($term_id, $admin_terms)) {
                                 $term_role_list[] = $term_names[$term_id];
                             } elseif (isset($strict_terms['restrictions'][$role_handle][$term_id]) || isset($strict_terms['unrestrictions'][$role_handle]) && is_array($strict_terms['unrestrictions'][$role_handle]) && !isset($strict_terms['unrestrictions'][$role_handle][$term_id])) {
                                 $term_role_list[] = "<span class='rs-backylw'><a {$title}{$limit_style}class='{$link_class}{$limit_class}' href='{$url}#item-{$term_id}'>" . $term_names[$term_id] . '</a></span>';
                             } else {
                                 $term_role_list[] = "<a {$title}{$limit_style}class='{$link_class}{$limit_class}' href='{$url}#item-{$term_id}'>" . $term_names[$term_id] . '</a>';
                             }
                         }
                         $html .= "\r\n" . "<tr{$style}>" . "<td>" . str_replace(' ', '&nbsp;', $role_display) . "</td>" . '<td>' . implode(', ', $term_role_list) . '</td>' . "</tr>";
                         $style = ' class="alternate"' == $style ? ' class="rs-backwhite"' : ' class="alternate"';
                     }
                 }
                 $html .= '</tbody></table>';
                 $html .= '</li></ul><br />';
             }
             // end foreach content date range
         }
         // end foreach role duration date range
     }
     // end foreach taxonomy
     require_once dirname(__FILE__) . '/object_roles_list.php';
     $html .= scoper_object_roles_list($user, array('enforce_duration_limits' => false, 'is_user_profile' => $viewing_own_profile, 'echo' => false));
     if ($groups_only) {
         //if ( empty($rs_blog_roles) && empty($term_role_list) && empty($got_obj_roles) )
         if ($html) {
             echo '<div>';
             echo "<h3>{$group_caption}</h3>";
             echo $html;
             echo '</div>';
             if (IS_MU_RS) {
                 echo '<br /><hr /><br />';
             }
         }
         //echo '<p>' . __('No roles are assigned to this group.', 'scoper'), '</p>';
     } else {
         echo $html;
         echo '</div>';
     }
 }
Exemple #19
0
function scoper_options($sitewide = false, $customize_defaults = false)
{
    if (!is_option_administrator_rs() || $sitewide && function_exists('is_super_admin') && !is_super_admin()) {
        wp_die(__awp('Cheatin&#8217; uh?'));
    }
    if ($sitewide) {
        $customize_defaults = false;
    }
    // this is intended only for storing custom default values for blog-specific options
    $ui = new ScoperOptionUI($sitewide, $customize_defaults);
    if (isset($_POST['all_otype_options'])) {
        wpp_cache_flush($sitewide);
        //global $wp_rewrite;
        //if ( ! empty($wp_rewrite) )
        //	$wp_rewrite->flush_rules();
        if (isset($_POST['rs_role_resync'])) {
            ScoperAdminLib::sync_wproles();
        }
        if (isset($_POST['rs_defaults'])) {
            $msg = __('Role Scoper options were reset to defaults.', 'scoper');
        } elseif (isset($_POST['rs_flush_cache'])) {
            $msg = __('The persistent cache was flushed.', 'scoper');
        } else {
            $msg = __('Role Scoper options were updated.', 'scoper');
        }
        // submittee_rs.php fielded this submission, but output the message here.
        echo '<div id="message" class="updated fade"><p>';
        echo $msg;
        echo '</p></div>';
    }
    global $scoper, $scoper_admin;
    define('SCOPER_REALM_ADMIN_RS', 1);
    // We need to access all config items here, even if they are normally removed due to disabling
    $scoper->load_config();
    // scoper_default_otype_options is hookable for other plugins to add pertinent items for their data sources
    scoper_refresh_default_options();
    scoper_refresh_default_otype_options();
    global $scoper_default_otype_options;
    $ui->def_otype_options = $scoper_default_otype_options;
    $ui->all_options = array();
    $ui->all_otype_options = array();
    $ui->tab_captions = array('features' => __('Features', 'scoper'), 'advanced' => __('Advanced', 'scoper'), 'realm' => __('Realm', 'scoper'), 'rs_role_definitions' => __('RS Role Definitions', 'scoper'), 'wp_role_definitions' => __('WP Role Definitions', 'scoper'), 'optscope' => __('Option Scope', 'scoper'));
    $ui->section_captions = array('features' => array('user_groups' => __('User Groups', 'scoper'), 'front_end' => __('Front End', 'scoper'), 'pages_listing' => __('Pages Listing', 'scoper'), 'categories_listing' => __('Categories Listing', 'scoper'), 'content_maintenance' => __('Content Maintenance', 'scoper'), 'role_assignment' => __('Role Assignment', 'scoper'), 'nav_menu_management' => __('Nav Menu Management', 'scoper'), 'media_library' => __('Media Library', 'scoper'), 'file_filtering' => __('File Filtering', 'scoper'), 'date_limits' => __('Role Date Limits', 'scoper'), 'internal_cache' => __('Internal Cache', 'scoper'), 'version' => __('Version', 'scoper'), 'rss_feeds' => __('RSS Feeds', 'scoper'), 'hidden_content_teaser' => __('Hidden Content Teaser', 'scoper')), 'advanced' => array('role_basis' => __('Role Basis', 'scoper'), 'page_structure' => __('Page Structure', 'scoper'), 'user_profile' => __('User Profile', 'scoper'), 'user_management' => __('User Management', 'scoper'), 'administrator_definition' => __('Administrator Definition', 'scoper'), 'limited_editing_elements' => __('Limited Editing Elements', 'scoper'), 'role_assignment_interface' => __('Role Assignment Interface', 'scoper'), 'custom_columns' => __('Custom Columns', 'scoper'), 'additional_object_roles' => __('Additional Object Roles', 'scoper')), 'realm' => array('term_object_scopes' => __('Term / Object Scope', 'scoper'), 'taxonomy_usage' => __('Taxonomy Usage', 'scoper'), 'post_type_usage' => __('Post Type Usage', 'scoper'), 'term_scope' => __('Term Scope', 'scoper'), 'object_scope' => __('Object Scope', 'scoper'), 'access_types' => __('Access Types', 'scoper')), 'rs_role_definitions' => array('' => ''), 'wp_role_definitions' => array('' => ''));
    // TODO: replace individual _e calls with these (and section, tab captions)
    $ui->option_captions = array('persistent_cache' => __('Cache roles and groups to disk', 'scoper'), 'define_usergroups' => __('Enabled', 'scoper'), 'group_ajax' => __('Use jQuery selection UI', 'scoper'), 'group_requests' => __('Enable membership requests', 'scoper'), 'group_recommendations' => __('Enable membership recommendations', 'scoper'), 'enable_group_roles' => __('Apply Group Roles', 'scoper'), 'enable_user_roles' => __('Apply User Roles', 'scoper'), 'custom_user_blogcaps' => __('Support WP Custom User Caps', 'scoper'), 'no_frontend_admin' => __('Assume No Front-end Admin', 'scoper'), 'indicate_blended_roles' => __('Indicate blended roles', 'scoper'), 'version_update_notice' => __('Notify on Version Updates', 'scoper'), 'strip_private_caption' => __('Suppress "Private:" Caption', 'scoper'), 'display_hints' => __('Display Administrative Hints', 'scoper'), 'hide_non_editor_admin_divs' => __('Specified element IDs also require the following site-wide Role:', 'scoper'), 'role_admin_blogwide_editor_only' => __('Roles and Restrictions can be set:', 'scoper'), 'feed_link_http_auth' => __('HTTP Authentication Request in RSS Feed Links', 'scoper'), 'rss_private_feed_mode' => __('Display mode for readable private posts', 'scoper'), 'rss_nonprivate_feed_mode' => __('Display mode for readable non-private posts', 'scoper'), 'feed_teaser' => __('Feed Replacement Text (use %permalink% for post URL)', 'scoper'), 'rs_page_reader_role_objscope' => $scoper->role_defs->get_display_name('rs_page_reader'), 'rs_page_author_role_objscope' => $scoper->role_defs->get_display_name('rs_page_author'), 'rs_post_reader_role_objscope' => $scoper->role_defs->get_display_name('rs_post_reader'), 'rs_post_author_role_objscope' => $scoper->role_defs->get_display_name('rs_post_author'), 'lock_top_pages' => __('Pages can be set or removed from Top Level by:', 'scoper'), 'display_user_profile_groups' => __('Display User Groups', 'scoper'), 'display_user_profile_roles' => __('Display User Roles', 'scoper'), 'user_role_assignment_csv' => __('Users CSV Entry', 'scoper'), 'admin_others_attached_files' => __('Non-editors see other users\' attached uploads', 'scoper'), 'admin_others_unattached_files' => __('Non-editors see other users\' unattached uploads', 'scoper'), 'remap_page_parents' => __('Remap pages to visible ancestor', 'scoper'), 'enforce_actual_page_depth' => __('Enforce actual page depth', 'scoper'), 'remap_thru_excluded_page_parent' => __('Remap through excluded page parent', 'scoper'), 'remap_term_parents' => __('Remap terms to visible ancestor', 'scoper'), 'enforce_actual_term_depth' => __('Enforce actual term depth', 'scoper'), 'remap_thru_excluded_term_parent' => __('Remap through excluded term parent', 'scoper'), 'limit_user_edit_by_level' => __('Limit User Edit by Level', 'scoper'), 'file_filtering' => __('Filter Uploaded File Attachments', 'scoper'), 'file_filtering_regen_key' => __('File Filtering Reset Key', 'scoper'), 'mu_sitewide_groups' => __('Share groups network-wide', 'scoper'), 'role_duration_limits' => __('Enable Role Duration Limits', 'scoper'), 'role_content_date_limits' => __('Enable Content Date Limits', 'scoper'), 'filter_users_dropdown' => __('Filter Users Dropdown', 'scoper'), 'restrictions_column' => __('Restrictions Column', 'scoper'), 'term_roles_column' => __('Term Roles Column', 'scoper'), 'object_roles_column' => __('Object Roles Column', 'scoper'), 'admin_nav_menu_filter_items' => __('List only user-editable content as available items', 'scoper'), 'do_teaser' => __('Enable', 'scoper'), 'admin_css_ids' => __('Limited Editing Elements', 'scoper'), 'limit_object_editors' => __('Limit eligible users for object-specific editing roles', 'scoper'), 'private_items_listable' => __('Include Private Pages in listing if user can read them', 'scoper'), 'use_term_roles' => __('settings', 'scoper'), 'disabled_access_types' => __('settings', 'scoper'), 'user_role_caps' => __('settings', 'scoper'), 'require_moderate_comments_cap' => __('Require moderate_comments capability', 'scoper'));
    $ui->form_options = array('features' => array('user_groups' => array('define_usergroups', 'group_ajax', 'group_requests', 'group_recommendations', 'mu_sitewide_groups'), 'front_end' => array('strip_private_caption', 'no_frontend_admin'), 'pages_listing' => array('private_items_listable', 'remap_page_parents', 'enforce_actual_page_depth', 'remap_thru_excluded_page_parent'), 'categories_listing' => array('remap_term_parents', 'enforce_actual_term_depth', 'remap_thru_excluded_term_parent'), 'content_maintenance' => array('default_private', 'sync_private', 'filter_users_dropdown', 'require_moderate_comments_cap'), 'nav_menu_management' => array('admin_nav_menu_filter_items'), 'role_assignment' => array('role_admin_blogwide_editor_only'), 'media_library' => array('admin_others_attached_files', 'admin_others_unattached_files'), 'file_filtering' => array('file_filtering', 'file_filtering_regen_key'), 'date_limits' => array('role_duration_limits', 'role_content_date_limits'), 'internal_cache' => array('persistent_cache'), 'version' => array('version_update_notice'), 'rss_feeds' => array('feed_link_http_auth', 'rss_private_feed_mode', 'rss_nonprivate_feed_mode', 'feed_teaser'), 'hidden_content_teaser' => array('do_teaser')), 'advanced' => array('role_basis' => array('enable_group_roles', 'enable_user_roles', 'custom_user_blogcaps'), 'page_structure' => array('lock_top_pages'), 'user_profile' => array('display_user_profile_groups', 'display_user_profile_roles'), 'user_management' => array('limit_user_edit_by_level'), 'limited_editing_elements' => array('admin_css_ids', 'hide_non_editor_admin_divs'), 'role_assignment_interface' => array('limit_object_editors', 'indicate_blended_roles', 'display_hints', 'user_role_assignment_csv'), 'custom_columns' => array('restrictions_column', 'term_roles_column', 'object_roles_column'), 'additional_object_roles' => array('rs_page_reader_role_objscope', 'rs_post_reader_role_objscope', 'rs_page_author_role_objscope', 'rs_post_author_role_objscope')), 'realm' => array('term_object_scopes' => array('use_term_roles'), 'access_types' => array('disabled_access_types')), 'rs_role_definitions' => array('' => array('user_role_caps')));
    if (IS_MU_RS) {
        if ($sitewide) {
            $available_form_options = $ui->form_options;
        }
        global $scoper_options_sitewide;
        global $rvy_options_sitewide;
        foreach ($ui->form_options as $tab_name => $sections) {
            foreach ($sections as $section_name => $option_names) {
                if ($sitewide) {
                    $ui->form_options[$tab_name][$section_name] = array_intersect($ui->form_options[$tab_name][$section_name], array_keys($scoper_options_sitewide));
                } else {
                    $ui->form_options[$tab_name][$section_name] = array_diff($ui->form_options[$tab_name][$section_name], array_keys($scoper_options_sitewide));
                }
            }
        }
        // WP Role Defs display follows RS Role Defs
        if (!empty($ui->form_options['rs_role_defs'][''])) {
            $ui->form_options['wp_role_defs'][''] = array('');
        }
        foreach ($ui->form_options as $tab_name => $sections) {
            foreach (array_keys($sections) as $section_name) {
                if (empty($ui->form_options[$tab_name][$section_name])) {
                    unset($ui->form_options[$tab_name][$section_name]);
                }
            }
        }
    }
    $ui->display_hints = scoper_get_option('display_hints', $sitewide, $customize_defaults);
    ?>

<div class='wrap'>
<?php 
    echo '<form action="" method="post">';
    wp_nonce_field('scoper-update-options');
    if ($sitewide) {
        echo "<input type='hidden' name='rs_options_doing_sitewide' value='1' />";
    }
    if ($customize_defaults) {
        echo "<input type='hidden' name='rs_options_customize_defaults' value='1' />";
    }
    ?>

<table width = "100%"><tr>
<td width = "90%">
<h2><?php 
    if ($sitewide) {
        _e('Role Scoper Network Options', 'scoper');
    } elseif ($customize_defaults) {
        _e('Role Scoper Default Site Options', 'scoper');
    } elseif (IS_MU_RS) {
        _e('Role Scoper Single Site Options', 'scoper');
    } else {
        _e('Role Scoper Options', 'scoper');
    }
    ?>

</h2>
</td>
<td>
<div class="submit" style="border:none;float:right;margin:0;">
<input type="submit" name="rs_submit" class="button-primary" value="<?php 
    _e('Update &raquo;', 'scoper');
    ?>
" />
</div>
</td>
</tr></table>
<?php 
    if ($sitewide) {
        $color_class = 'rs-backgreen';
        echo '<p style="margin-top:0">';
        _e('These settings will be applied to all sites.', 'scoper');
        echo '</p>';
    } elseif ($customize_defaults) {
        $color_class = 'rs-backgray';
        echo '<p style="margin-top:0">';
        _e('These are the <strong>default</strong> settings for options which can be adjusted per-site.', 'scoper');
        echo '</p>';
    } else {
        $color_class = 'rs-backtan';
    }
    $class_selected = "agp-selected_agent agp-agent {$color_class}";
    $class_unselected = "agp-unselected_agent agp-agent";
    // todo: prevent line breaks in these links
    $js_call = "agp_swap_display('rs-features', 'rs-realm', 'rs_show_features', 'rs_show_realm', '{$class_selected}', '{$class_unselected}');";
    $js_call .= "agp_swap_display('', 'rs-roledefs', '', 'rs_show_roledefs', '{$class_selected}', '{$class_unselected}');";
    $js_call .= "agp_swap_display('', 'rs-advanced', '', 'rs_show_advanced', '{$class_selected}', '{$class_unselected}');";
    $js_call .= "agp_swap_display('', 'wp-roledefs', '', 'wp_show_roledefs', '{$class_selected}', '{$class_unselected}');";
    $js_call .= "agp_swap_display('', 'rs-optscope', '', 'rs_show_optscope', '{$class_selected}', '{$class_unselected}');";
    echo "<ul class='rs-list_horiz' style='margin-bottom:-0.1em'>" . "<li class='{$class_selected}'>" . "<a id='rs_show_features' href='javascript:void(0)' onclick=\"{$js_call}\">" . $ui->tab_captions['features'] . '</a>' . '</li>';
    if (!empty($ui->form_options['advanced'])) {
        $js_call = "agp_swap_display('rs-advanced', 'rs-features', 'rs_show_advanced', 'rs_show_features', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-realm', '', 'rs_show_realm', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-roledefs', '', 'rs_show_roledefs', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'wp-roledefs', '', 'wp_show_roledefs', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-optscope', '', 'rs_show_optscope', '{$class_selected}', '{$class_unselected}');";
        echo "<li class='{$class_unselected}'>" . "<a id='rs_show_advanced' href='javascript:void(0)' onclick=\"{$js_call}\">" . $ui->tab_captions['advanced'] . '</a>' . '</li>';
    }
    if (!empty($ui->form_options['realm'])) {
        $js_call = "agp_swap_display('rs-realm', 'rs-features', 'rs_show_realm', 'rs_show_features', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-roledefs', '', 'rs_show_roledefs', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-advanced', '', 'rs_show_advanced', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'wp-roledefs', '', 'wp_show_roledefs', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-optscope', '', 'rs_show_optscope', '{$class_selected}', '{$class_unselected}');";
        echo "<li class='{$class_unselected}'>" . "<a id='rs_show_realm' href='javascript:void(0)' onclick=\"{$js_call}\">" . $ui->tab_captions['realm'] . '</a>' . '</li>';
    }
    if (!empty($ui->form_options['rs_role_definitions'])) {
        $js_call = "agp_swap_display('rs-roledefs', 'rs-features', 'rs_show_roledefs', 'rs_show_features', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-realm', '', 'rs_show_realm', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-advanced', '', 'rs_show_advanced', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'wp-roledefs', '', 'wp_show_roledefs', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-optscope', '', 'rs_show_optscope', '{$class_selected}', '{$class_unselected}');";
        echo "<li class='{$class_unselected}'>" . "<a id='rs_show_roledefs' href='javascript:void(0)' onclick=\"{$js_call}\">" . $ui->tab_captions['rs_role_definitions'] . '</a>' . '</li>';
        $js_call = "agp_swap_display('wp-roledefs', 'rs-features', 'wp_show_roledefs', 'rs_show_features', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-realm', '', 'rs_show_realm', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-advanced', '', 'rs_show_advanced', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-roledefs', '', 'rs_show_roledefs', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-optscope', '', 'rs_show_optscope', '{$class_selected}', '{$class_unselected}');";
        echo "<li class='{$class_unselected}'>" . "<a id='wp_show_roledefs' href='javascript:void(0)' onclick=\"{$js_call}\">" . $ui->tab_captions['wp_role_definitions'] . '</a>' . '</li>';
    }
    if ($sitewide) {
        $js_call = "agp_swap_display('rs-optscope', 'rs-features', 'rs_show_optscope', 'rs_show_features', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-advanced', '', 'rs_show_advanced', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-roledefs', '', 'rs_show_roledefs', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'rs-realm', '', 'rs_show_realm', '{$class_selected}', '{$class_unselected}');";
        $js_call .= "agp_swap_display('', 'wp-roledefs', '', 'wp_show_roledefs', '{$class_selected}', '{$class_unselected}');";
        echo "<li class='{$class_unselected}'>" . "<a id='rs_show_optscope' href='javascript:void(0)' onclick=\"{$js_call}\">" . $ui->tab_captions['optscope'] . '</a>' . '</li>';
    }
    echo '</ul>';
    // ------------------------- BEGIN Features tab ---------------------------------
    $tab = 'features';
    echo "<div id='rs-features' style='clear:both;margin:0' class='rs-options {$color_class}'>";
    if (scoper_get_option('display_hints', $sitewide, $customize_defaults)) {
        echo '<div class="rs-optionhint">';
        _e("This page enables <strong>optional</strong> adjustment of Role Scoper's features. For most installations, the default settings are fine.", 'scoper');
        require_once dirname(__FILE__) . '/misc/version_notice_rs.php';
        $message = scoper_pp_msg();
        echo "<br /><br /><div>{$message}</div>";
        if (IS_MU_RS && function_exists('is_super_admin') && is_super_admin()) {
            if ($sitewide) {
                if (!$customize_defaults) {
                    $link_open = "<a href='admin.php?page=rs-options'>";
                    $link_close = '</a>';
                    echo ' ';
                    if (awp_ver('3.1')) {
                        _e('Note that, depending on your configuration, site-specific options may also be available.', 'scoper');
                    } else {
                        printf(__('Note that, depending on your configuration, %1$s site-specific options%2$s may also be available.', 'scoper'), $link_open, $link_close);
                    }
                }
            } else {
                $link_open = awp_ver('3.1') ? "<a href='network/sites.php?page=rs-site_options'>" : "<a href='admin.php?page=rs-site_options'>";
                $link_close = '</a>';
                echo ' ';
                printf(__('Note that, depending on your configuration, %1$s network-wide options%2$s may also be available.', 'scoper'), $link_open, $link_close);
            }
        }
        echo '</div>';
    }
    $table_class = 'form-table rs-form-table';
    ?>


<table class="<?php 
    echo $table_class;
    ?>
" id="rs-admin_table">

<?php 
    // possible TODO: replace redundant hardcoded IDs with $id
    $section = 'user_groups';
    // --- USER GROUPS SECTION ---
    if (!empty($ui->form_options[$tab][$section])) {
        ?>

	<tr valign="top"><th scope="row">
	<?php 
        echo $ui->section_captions[$tab][$section];
        ?>

	</th><td>
	
	<?php 
        $hint = '';
        $ui->option_checkbox('define_usergroups', $tab, $section, $hint, '<br />');
        if (IS_MU_RS) {
            $hint = __('If enabled, each user group will be available for role assignment in any site.  Any existing site-specific groups will be unavailable.  Group role assignments are still site-specific.', 'scoper');
            $ui->option_checkbox('mu_sitewide_groups', $tab, $section, $hint, '');
        }
        $hint = __('Specify group membership via a search/results interface, instead of simple checkboxes.', 'scoper');
        $js_call = "agp_display_if('group_requests_div', 'group_ajax');agp_display_if('group_recommendations_div', 'group_ajax');";
        $ret = $ui->option_checkbox('group_ajax', $tab, $section, $hint, '', array('js_call' => $js_call));
        $group_ajax = $ret['val'] || !$ret['in_scope'];
        $hint = __('A general role of Group Applicant (or the request_group_membership capability) allows a user to request membership in any existing group via their user profile.', 'scoper');
        $css_display = $group_ajax ? 'block' : 'none';
        echo "<div id='group_requests_div' style='display:{$css_display}; margin-top: 1em;margin-left:2em;'>";
        $ui->option_checkbox('group_requests', $tab, $section, $hint, '');
        echo '</div>';
        $hint = __('A Group Moderator role (general or group-specific) allows a user to recommend group members, possibly in response to requests.  This can serve as a two-tier approval mechanism.', 'scoper');
        $css_display = $group_ajax ? 'block' : 'none';
        echo "<div id='group_recommendations_div' style='display:{$css_display}; margin-top: 1em;margin-left:2em;'>";
        $ui->option_checkbox('group_recommendations', $tab, $section, $hint, '');
        echo '</div>';
        ?>

	</td></tr>
<?php 
    }
    // any options accessable in this section
    // --- FRONT END SECTION ---
    $section = 'front_end';
    if (!empty($ui->form_options[$tab][$section])) {
        ?>

	<tr valign="top">
	<th scope="row"><?php 
        echo $ui->section_captions[$tab][$section];
        ?>
</th>
	<td>

	<?php 
        $hint = __('Remove the "Private:" and "Protected" prefix from Post, Page titles', 'scoper');
        $ui->option_checkbox('strip_private_caption', $tab, $section, $hint, '<br />');
        $hint = __('Reduce memory usage for front-end access by assuming no content, categories or users will be created or edited there. Worst case scenario if you assume wrong: manually assign roles/restrictions to new content or re-sync user roles via plugin re-activation.', 'scoper');
        $ui->option_checkbox('no_frontend_admin', $tab, $section, $hint, '');
        ?>

	</td></tr>
<?php 
    }
    // any options accessable in this section
    $section = 'pages_listing';
    if (!empty($ui->form_options[$tab][$section])) {
        ?>

	<tr valign="top">
	<th scope="row"><?php 
        // --- PAGES LISTING SECTION ---
        echo $ui->section_captions[$tab][$section];
        ?>
</th>
	<td>

	<?php 
        $otype_caption = __('Include Private %s in listing if user can read them', 'scoper');
        $hint = __('Determines whether administrators, editors and users who have been granted access to a private page will see it in their sidebar or topbar page listing.', 'scoper');
        $ui->otype_option_checkboxes('private_items_listable', $otype_caption, $tab, $section, $hint, '<br /><br />', array('caption_header' => false));
        $hint = __('If a page\'s parent is not visible to the user, it will be listed below a visible grandparent instead.', 'scoper');
        $js_call = "agp_display_if('enforce_actual_page_depth_div', 'remap_page_parents');agp_display_if('remap_thru_excluded_page_parent_div', 'remap_page_parents');";
        $ret = $ui->option_checkbox('remap_page_parents', $tab, $section, $hint, '', array('js_call' => $js_call));
        $do_remap = $ret['val'] || !$ret['in_scope'];
        $hint = __('When remapping page parents, apply any depth limits to the actual depth below the requested root page.  If disabled, depth limits apply to apparant depth following remap.', 'scoper');
        $css_display = $do_remap ? 'block' : 'none';
        echo "<div id='enforce_actual_page_depth_div' style='display:{$css_display}; margin-top: 1em;margin-left:2em;'>";
        $ui->option_checkbox('enforce_actual_page_depth', $tab, $section, $hint, '');
        echo '</div>';
        $hint = __('Remap a page to next visible ancestor even if some hidden ancestors were explicitly excluded in the get_pages / list_pages call.', 'scoper');
        $css_display = $do_remap ? 'block' : 'none';
        echo "<div id='remap_thru_excluded_page_parent_div' style='display:{$css_display}; margin-top: 1em;margin-left:2em;'>";
        $ui->option_checkbox('remap_thru_excluded_page_parent', $tab, $section, $hint, '');
        echo '</div>';
        ?>

	</td></tr>
<?php 
    }
    // any options accessable in this section
    $section = 'categories_listing';
    if (!empty($ui->form_options[$tab][$section])) {
        ?>

	<tr valign="top">
	<th scope="row"><?php 
        // --- CATEGORIES LISTING SECTION ---
        echo $ui->section_captions[$tab][$section];
        ?>
</th>
	<td>

	<?php 
        $hint = __('If a category\'s parent is not visible to the user, it will be listed below a visible grandparent instead.', 'scoper');
        $js_call = "agp_display_if('enforce_actual_term_depth_div', 'remap_term_parents');agp_display_if('remap_thru_excluded_term_parent_div', 'remap_term_parents');";
        $ret = $ui->option_checkbox('remap_term_parents', $tab, $section, $hint, '', array('js_call' => $js_call));
        $do_remap = $ret['val'] || !$ret['in_scope'];
        $hint = __('When remapping category parents, apply any depth limits to the actual depth below the requested root category.  If disabled, depth limits apply to apparant depth following remap.', 'scoper');
        $css_display = $do_remap ? 'block' : 'none';
        echo "<div id='enforce_actual_term_depth_div' style='display:{$css_display}; margin-top: 1em;margin-left:2em;'>";
        $ret = $ui->option_checkbox('enforce_actual_term_depth', $tab, $section, $hint, '');
        echo '</div>';
        $hint = __('Remap a category to next visible ancestor even if some hidden ancestors were explicitly excluded in the get_terms / get_categories call.', 'scoper');
        $css_display = $do_remap ? 'block' : 'none';
        echo "<div id='remap_thru_excluded_term_parent_div' style='display:{$css_display}; margin-top: 1em;margin-left:2em;'>";
        $ret = $ui->option_checkbox('remap_thru_excluded_term_parent', $tab, $section, $hint, '');
        echo '</div>';
        ?>
	

	</td></tr>
<?php 
    }
    // any options accessable in this section
    $section = 'content_maintenance';
    if (!empty($ui->form_options[$tab][$section])) {
        ?>

	<tr valign="top">
	<th scope="row"><?php 
        // --- CONTENT MAINTENANCE SECTION ---
        echo $ui->section_captions[$tab][$section];
        ?>

	</th><td>

	<?php 
        $caption = __('Default new %s to Private visibility', 'scoper');
        $hint = __('Note: this does not apply to Quickposts or XML-RPC submissions.', 'scoper');
        $ui->otype_option_checkboxes('default_private', $caption, $tab, $section, $hint, '<br /><br />');
        $caption = __('Auto-set %s to Private visibility if Reader role is restricted', 'scoper');
        $hint = __('Note: this is only done if the Reader role is restricted via Post/Page edit form.', 'scoper');
        $ui->otype_option_checkboxes('sync_private', $caption, $tab, $section, $hint, '<br /><br />');
        $hint = __('If enabled, Post Author and Page Author selection dropdowns will be filtered based on scoped roles.', 'scoper');
        $ret = $ui->option_checkbox('filter_users_dropdown', $tab, $section, $hint, '<br />');
        $hint = __('If enabled, Post Author / Editors cannot moderate comments unless their assigned role(s) include the moderate_comments capability.', 'scoper');
        $ret = $ui->option_checkbox('require_moderate_comments_cap', $tab, $section, $hint, '');
        ?>


	</td>
	</tr>
<?php 
    }
    // any options accessable in this section
    $section = 'nav_menu_management';
    if (!empty($ui->form_options[$tab][$section])) {
        ?>

	<tr valign="top">
	<th scope="row"><?php 
        echo $ui->section_captions[$tab][$section];
        // --- NAV MENU MANAGEMENT SECTION ---
        ?>
</th><td>
	
	<?php 
        $hint = '';
        $ui->option_checkbox('admin_nav_menu_filter_items', $tab, $section, $hint, '');
        ?>

		
	</td></tr>
<?php 
    }
    // any options accessable in this section
    $section = 'role_assignment';
    if (!empty($ui->form_options[$tab][$section])) {
        ?>

	<tr valign="top">
	<th scope="row"><?php 
        // --- ROLE ASSIGNMENT SECTION ---
        echo $ui->section_captions[$tab][$section];
        ?>

	</th><td>
<?php 
        if (in_array('role_admin_blogwide_editor_only', $ui->form_options[$tab][$section])) {
            $id = 'role_admin_blogwide_editor_only';
            $ui->all_options[] = $id;
            $current_setting = strval(scoper_get_option($id, $sitewide, $customize_defaults));
            // force setting and corresponding keys to string, to avoid quirks with integer keys
            if ($current_setting === '') {
                $current_setting = '0';
            }
            ?>

		<div class="agp-vspaced_input">
		<label for="role_admin_blogwide_editor_only">
		<?php 
            echo $ui->option_captions['role_admin_blogwide_editor_only'];
            $captions = array('0' => __('by the Author or Editor of any Post/Category/Page', 'scoper'), '1' => __('by site-wide Editors and Administrators', 'scoper'), 'admin_content' => __('by Content Administrators only', 'scoper'), 'admin' => __('by User Administrators only', 'scoper'));
            // legacy-stored 'admin' in older versions
            foreach ($captions as $key => $value) {
                $key = strval($key);
                echo "<div style='margin: 0 0 0.5em 2em;'><label for='{$id}_{$key}'>";
                $checked = $current_setting === $key ? "checked='checked'" : '';
                echo "<input name='{$id}' type='radio' id='{$id}_{$key}' value='{$key}' {$checked} />";
                echo $value;
                echo '</label></div>';
            }
            ?>

		<span class="rs-subtext">
		<?php 
            if ($ui->display_hints) {
                _e('Specify which users can assign and restrict roles <strong>for their content</strong> - via Post/Page Edit Form or Roles/Restrictions sidebar menu.  For a description of Administrator roles, see the Advanced tab.', 'scoper');
            }
            ?>

		</span>
		</div>
	<?php 
        }
        // endif role_admin_blogwide_editor_only controlled in this option scope
        ?>

	</td>
	</tr>
<?php 
    }
    // any options accessable in this section
    $section = 'media_library';
    if (!empty($ui->form_options[$tab][$section])) {
        ?>

	<tr valign="top">
	<th scope="row"><?php 
        // --- MEDIA LIBRARY SECTION ---
        echo $ui->section_captions[$tab][$section];
        ?>

	</th><td>
<?php 
        $hint = __('For users who are not site-wide Editors, determines Media Library visibility of files uploaded by another user and now attached to a post which the logged user can edit.', 'scoper');
        $ret = $ui->option_checkbox('admin_others_attached_files', $tab, $section, $hint, '');
        $hint = __('For users who are not site-wide Editors, determines Media Library visibility of unattached files which were uploaded by another user.', 'scoper');
        $ret = $ui->option_checkbox('admin_others_unattached_files', $tab, $section, $hint, '');
        ?>

	</td>
	</tr>
<?php 
    }
    // any options accessable in this section
    $section = 'file_filtering';
    if (!empty($ui->form_options[$tab][$section])) {
        ?>

	<tr valign="top">
	<th scope="row"><?php 
        // --- ATTACHMENTS SECTION ---
        echo $ui->section_captions[$tab][$section];
        ?>
</th>
	<td>
	
	<?php 
        if (in_array('file_filtering', $ui->form_options[$tab][$section])) {
            $ui->all_options[] = 'file_filtering';
            $site_url = untrailingslashit(get_option('siteurl'));
            if (defined('DISABLE_ATTACHMENT_FILTERING')) {
                $content_dir_notice = __('<strong>Note</strong>: Direct access to uploaded file attachments will not be filtered because DISABLE_ATTACHMENT_FILTERING is defined, perhaps in wp-config.php or role-scoper.php', 'scoper');
            } elseif (MULTISITE && defined('SCOPER_NO_HTACCESS')) {
                $content_dir_notice = __('<strong>Note</strong>: Direct access to uploaded file attachments will not be filtered because SCOPER_NO_HTACCESS is defined, perhaps in wp-config.php or role-scoper.php', 'scoper');
            } else {
                require_once SCOPER_ABSPATH . '/rewrite-rules_rs.php';
                require_once SCOPER_ABSPATH . '/uploads_rs.php';
                $uploads = scoper_get_upload_info();
                if (!got_mod_rewrite()) {
                    $content_dir_notice = __('<strong>Note</strong>: Direct access to uploaded file attachments cannot be filtered because mod_rewrite is not enabled on your server.', 'scoper');
                } elseif (false === strpos($uploads['baseurl'], $site_url)) {
                    $content_dir_notice = __('<strong>Note</strong>: Direct access to uploaded file attachments cannot be filtered because your WP_CONTENT_DIR is not in the WordPress branch.', 'scoper');
                } elseif (!ScoperRewrite::site_config_supports_rewrite()) {
                    $content_dir_notice = __('<strong>Note</strong>: Direct access to uploaded file attachments will not be filtered due to your nonstandard UPLOADS path.', 'scoper');
                } else {
                    global $wp_rewrite;
                    if (empty($wp_rewrite->permalink_structure)) {
                        $content_dir_notice = __('<strong>Note</strong>: Direct access to uploaded file attachments cannot be filtered because WordPress permalinks are set to default.', 'scoper');
                    }
                }
            }
            $disabled = !empty($content_dir_notice);
            $attachment_filtering = !$disabled && scoper_get_option('file_filtering', $sitewide, $customize_defaults);
            ?>

		<label for="file_filtering">
		<input name="file_filtering" type="checkbox" id="file_filtering" <?php 
            echo $disabled;
            ?>
 value="1" <?php 
            checked(true, $attachment_filtering);
            ?>
 />
		<?php 
            echo $ui->option_captions['file_filtering'];
            ?>
</label>
		<br />
		<div class="rs-subtext">
		<?php 
            if ($ui->display_hints) {
                _e('Block direct URL access to images and other uploaded files in the WordPress uploads folder which are attached to post(s)/page(s) that the user cannot read.  A separate RewriteRule will be added to your .htaccess file for each protected file.  Non-protected files are returned with no script execution whatsoever.', 'scoper');
            }
            if ($attachment_filtering) {
                /*
                if ( $ui->display_hints) {
                	if ( IS_MU_RS && ! defined('SCOPER_MU_FILE_PROCESSING') ) {
                		echo '</div><div class="agp-vspaced_input" style="margin-top: 1em">';
                		_e("<strong>Note:</strong> The default WP-MU file request script, <strong>wp-content/blogs.php</strong>, requires a patch for compatibility with RS file filtering.  If you need the advanced cache control provided by blogs.php, review the notes in <strong>role-scoper/mu_wp_content_optional/blogs.php</strong> and copy it into wp-content if desired.  Otherwise, files will be accessed directly via header redirect following RS filtering.  If you decide to install the patched blogs.php, add the following line to wp-config.php:<br />&nbsp;&nbsp;&nbsp; define( 'SCOPER_MU_FILE_PROCESSING', true);", 'scoper');
                		echo '</div>';
                	}
                }
                */
            } elseif (!empty($content_dir_notice)) {
                echo '<br /><span class="rs-warning">';
                echo $content_dir_notice;
                echo '</span>';
            }
            ?>

		</div><br />
		
		<?php 
            $id = 'file_filtering_regen_key';
            $ui->all_options[] = $id;
            $val = scoper_get_option($id);
            echo "<div><label for='{$id}'>";
            echo $ui->option_captions[$id];
            ?>

		<input name="<?php 
            echo $id;
            ?>
" type="text" style="vertical-align:middle; width: 8em" id="<?php 
            echo $id;
            ?>
" value="<?php 
            echo $val;
            ?>
" />
		</label>
		</div>
		
		<?php 
            if ($ui->display_hints) {
                echo '<div class="rs-subtext">';
                if ($val) {
                    if (IS_MU_RS) {
                        _e('To force regeneration of file attachment access keys (at next site access), execute the following URL:', 'scoper');
                    } else {
                        _e('To force regeneration of file attachment access keys, execute the following URL:', 'scoper');
                    }
                    $url = site_url("index.php?action=expire_file_rules&key={$val}");
                    echo "<br />&nbsp;&nbsp;<a href='{$url}'>{$url}</a>";
                } else {
                    _e('Supply a custom key which will enable a support url to regenerate file access keys.  Then execute the url regularly (using your own cron service) to prevent long-term bookmarking of protected files.', 'scoper');
                }
                echo '</div>';
            }
            ?>

		<br />

		<?php 
            //printf( _ x('<strong>Note:</strong> FTP-uploaded files will not be filtered correctly until you run the %1$sAttachments Utility%2$s.', 'arguments are link open, link close', 'scoper'), "<a href='admin.php?page=rs-attachments_utility'>", '</a>');
            printf(__('<strong>Note:</strong> FTP-uploaded files will not be filtered correctly until you run the %1$sAttachments Utility%2$s.', 'scoper'), "<a href='admin.php?page=rs-attachments_utility'>", '</a>');
            echo '<br /><br />';
            _e('If WordPress or any plugin output visible PHP warnings during filtering of a protected image request, the image will not be successfully returned.', 'scoper');
            ?>

		<br />
	<?php 
        }
        ?>

	
	</td></tr>
<?php 
    }
    // any options accessable in this section
    $section = 'date_limits';
    if (!empty($ui->form_options[$tab][$section])) {
        ?>

	<tr valign="top">
	<th scope="row"><?php 
        echo $ui->section_captions[$tab][$section];
        // --- ROLE DATE LIMITS SECTION ---
        ?>
</th><td>
	
	<?php 
        $hint = __('Allow the delay or expiration of roles based on a specified date range.', 'scoper');
        $ret = $ui->option_checkbox('role_duration_limits', $tab, $section, $hint, '');
        $hint = __('Allow General Roles and Category Roles to be limited to content dated within in a specified range.', 'scoper');
        $ret = $ui->option_checkbox('role_content_date_limits', $tab, $section, $hint, '');
        ?>

	
	</td></tr>
<?php 
    }
    // any options accessable in this section
    $section = 'internal_cache';
    if (!empty($ui->form_options[$tab][$section])) {
        // --- PERSISTENT CACHE SECTION ---
        ?>

	<tr valign="top">
	<th scope="row"><?php 
        echo $ui->section_captions[$tab][$section];
        ?>
</th>
	<td>
		
	<?php 
        if (in_array('persistent_cache', $ui->form_options[$tab][$section])) {
            $ui->all_options[] = 'persistent_cache';
            $cache_selected = scoper_get_option('persistent_cache', $sitewide, $customize_defaults);
            $cache_enabled = $cache_selected && !defined('DISABLE_PERSISTENT_CACHE');
            ?>

		<label for="persistent_cache">
		<input name="persistent_cache" type="checkbox" id="persistent_cache" value="1" <?php 
            checked(true, $cache_enabled);
            ?>
 />
		<?php 
            echo $ui->option_captions['persistent_cache'];
            ?>
</label>
		<br />
		<span class="rs-subtext">
		<?php 
            if ($ui->display_hints) {
                _e('Group membership, role restrictions, role assignments and some filtered results (including term listings and WP page, category and bookmark listings) will be stored to disk, on a user-specific or group-specific basis where applicable.  This does not cache content such as post listings or page views.', 'scoper');
            }
            echo '</span>';
            $cache_msg = '';
            if ($cache_selected && !wpp_cache_test($cache_msg, 'scoper')) {
                echo '<div class="agp-vspaced_input"><span class="rs-warning">';
                echo $cache_msg;
                echo '</span></div>';
            } elseif ($cache_enabled && !file_exists('../rs_cache_flush.php') && !file_exists('..\\rs_cache_flush.php')) {
                echo '<div class="agp-vspaced_input"><span class="rs-warning">';
                _e('<strong>Note:</strong> The internal caching code contains numerous safeguards against corruption.  However, if it does become corrupted your site may be inaccessable.  For optimal reliability, copy rs_cache_flush.php into your WP root directory so it can be executed directly if needed.', 'scoper');
                echo '</span></div>';
            }
            ?>

		
		<?php 
            if ($cache_enabled) {
                ?>

		<br />
		<span class="submit" style="border:none;float:left;margin-top:0">
		<input type="submit" name="rs_flush_cache" value="<?php 
                _e('Flush Cache', 'scoper');
                ?>
" />
		</span>
		<?php 
            }
            ?>

	<?php 
        }
        ?>

		
	</td></tr>
<?php 
    }
    // any options accessable in this section
    $section = 'version';
    if (!empty($ui->form_options[$tab][$section])) {
        // --- VERSION SECTION ---
        ?>

	<tr valign="top">
	<th scope="row"><?php 
        echo $ui->section_captions[$tab][$section];
        ?>
</th>
	<td>
	
	<?php 
        if (in_array('version_update_notice', $ui->form_options[$tab][$section])) {
            $ui->all_options[] = 'version_update_notice';
            ?>

		<?php 
            printf(__("Role Scoper Version: %s", 'scoper'), SCOPER_VERSION);
            echo '<br />';
            printf(__("Database Schema Version: %s", 'scoper'), SCOPER_DB_VERSION);
            echo '<br />';
            global $wp_version;
            printf(__("WordPress Version: %s", 'scoper'), $wp_version);
            echo '<br />';
            printf(__("PHP Version: %s", 'scoper'), phpversion());
            echo '<br />';
            $hint = '';
            $ui->option_checkbox('version_update_notice', $tab, $section, $hint, '<br />');
            ?>

	<?php 
        }
        ?>

		
	</td></tr>
<?php 
    }
    // any options accessable in this section
    $section = 'rss_feeds';
    if (!empty($ui->form_options[$tab][$section])) {
        ?>

	<tr valign="top">
	<th scope="row"><?php 
        // --- RSS FEEDS SECTION ---
        echo $ui->section_captions[$tab][$section];
        ?>
</th>
	<td>
	
	<?php 
        if (in_array('feed_link_http_auth', $ui->form_options[$tab][$section])) {
            if (!defined('HTTP_AUTH_DISABLED_RS')) {
                $id = 'feed_link_http_auth';
                $ui->all_options[] = $id;
                $current_setting = scoper_get_option($id, $sitewide, $customize_defaults);
                echo $ui->option_captions['feed_link_http_auth'];
                echo "&nbsp;<select name='{$id}' id='{$id}'>";
                $captions = array(0 => __('never', 'scoper'), 1 => __('always', 'scoper'), 'logged' => __('for logged users', 'scoper'));
                foreach ($captions as $key => $value) {
                    $selected = $current_setting == $key ? 'selected="selected"' : '';
                    echo "\n\t<option value='{$key}' " . $selected . ">{$captions[$key]}</option>";
                }
                echo '</select>&nbsp;';
                echo "<br />";
                echo '<span class="rs-subtext">';
                if ($ui->display_hints) {
                    _e('Suffix RSS feed links with an extra parameter to trigger required HTTP authentication. Note that anonymous and cookie-based RSS will still be available via the standard feed URL.', 'scoper');
                }
                echo '</span>';
            } else {
                echo '<span class="rs-warning">';
                _e('cannot use HTTP Authentication for RSS Feeds because another plugin has already defined the function "get_currentuserinfo"', 'scoper');
                echo '</span>';
            }
            echo "<br /><br />";
        }
        ?>

		
	<?php 
        if (in_array('rss_private_feed_mode', $ui->form_options[$tab][$section])) {
            $ui->all_options[] = 'rss_private_feed_mode';
            //echo ( _ x( 'Display', 'prefix to RSS content dropdown', 'scoper' ) );
            echo __('Display', 'scoper');
            echo '&nbsp;<select name="rss_private_feed_mode" id="rss_private_feed_mode">';
            $captions = array('full_content' => __("Full Content", 'scoper'), 'excerpt_only' => __("Excerpt Only", 'scoper'), 'title_only' => __("Title Only", 'scoper'));
            foreach ($captions as $key => $value) {
                $selected = scoper_get_option('rss_private_feed_mode', $sitewide, $customize_defaults) == $key ? 'selected="selected"' : '';
                echo "\n\t<option value='{$key}' " . $selected . ">{$captions[$key]}</option>";
            }
            echo '</select>&nbsp;';
            //echo ( _ x( 'for readable private posts', 'suffix to RSS content dropdown', 'scoper' ) );
            echo __('for readable private posts', 'scoper');
            echo "<br />";
        }
        ?>

	
	<?php 
        if (in_array('rss_nonprivate_feed_mode', $ui->form_options[$tab][$section])) {
            $ui->all_options[] = 'rss_nonprivate_feed_mode';
            //echo ( _ x( 'Display', 'prefix to RSS content dropdown', 'scoper' ) );
            echo __('Display', 'scoper');
            echo '&nbsp;<select name="rss_nonprivate_feed_mode" id="rss_nonprivate_feed_mode">';
            $captions = array('full_content' => __("Full Content", 'scoper'), 'excerpt_only' => __("Excerpt Only", 'scoper'), 'title_only' => __("Title Only", 'scoper'));
            foreach ($captions as $key => $value) {
                $selected = scoper_get_option('rss_nonprivate_feed_mode', $sitewide, $customize_defaults) == $key ? 'selected="selected"' : '';
                echo "\n\t<option value='{$key}' " . $selected . ">{$captions[$key]}</option>";
            }
            echo '</select>&nbsp;';
            //echo ( _ x( 'for readable non-private posts', 'suffix to RSS content dropdown', 'scoper' ) );
            echo __('for readable non-private posts', 'scoper');
            echo "<br />";
            ?>

		<span class="rs-subtext">
		<?php 
            if ($ui->display_hints) {
                _e('Since some browsers will cache feeds without regard to user login, block RSS content even for qualified users.', 'scoper');
            }
            ?>

		</span>
		<br /><br />
	<?php 
        }
        ?>

		
	<?php 
        if (in_array('feed_teaser', $ui->form_options[$tab][$section])) {
            $id = 'feed_teaser';
            $ui->all_options[] = $id;
            $val = htmlspecialchars(scoper_get_option($id, $sitewide, $customize_defaults));
            echo "<label for='{$id}'>";
            _e('Feed Replacement Text (use %permalink% for post URL)', 'scoper');
            echo "<br /><textarea name='{$id}' cols=60 rows=1 id='{$id}'>{$val}</textarea>";
            echo "</label>";
        }
        ?>

	
	</td></tr>
<?php 
    }
    // any options accessable in this section
    $section = 'hidden_content_teaser';
    if (!empty($ui->form_options[$tab][$section]) && in_array('do_teaser', $ui->form_options[$tab][$section])) {
        // for now, teaser option are all-or-nothing sitewide / blogwide
        ?>

	<tr valign="top">
	<th scope="row"><?php 
        // --- HIDDEN CONTENT TEASER SECTION ---
        echo $ui->section_captions[$tab][$section];
        ?>
</th>
	<td>
	<?php 
        // a "do teaser checkbox for each data source" that has a def_otype_options	entry
        $option_basename = 'do_teaser';
        if (isset($ui->def_otype_options[$option_basename])) {
            $ui->all_otype_options[] = $option_basename;
            $opt_vals = scoper_get_option($option_basename, $sitewide, $customize_defaults);
            if (!$opt_vals || !is_array($opt_vals)) {
                $opt_vals = array();
            }
            $do_teaser = array_merge($ui->def_otype_options[$option_basename], $opt_vals);
            $option_hide_private = 'teaser_hide_private';
            $ui->all_otype_options[] = $option_hide_private;
            $opt_vals = scoper_get_option($option_hide_private, $sitewide, $customize_defaults);
            if (!$opt_vals || !is_array($opt_vals)) {
                $opt_vals = array();
            }
            $hide_private = array_merge($ui->def_otype_options[$option_hide_private], $opt_vals);
            $option_use_teaser = 'use_teaser';
            $ui->all_otype_options[] = $option_use_teaser;
            $opt_vals = scoper_get_option($option_use_teaser, $sitewide, $customize_defaults);
            if (!$opt_vals || !is_array($opt_vals)) {
                $opt_vals = array();
            }
            $use_teaser = array_merge($ui->def_otype_options[$option_use_teaser], $opt_vals);
            $option_logged_only = 'teaser_logged_only';
            $ui->all_otype_options[] = $option_logged_only;
            $opt_vals = scoper_get_option($option_logged_only, $sitewide, $customize_defaults);
            if (!$opt_vals || !is_array($opt_vals)) {
                $opt_vals = array();
            }
            $logged_only = array_merge($ui->def_otype_options[$option_logged_only], $opt_vals);
            // loop through each source that has a default do_teaser setting defined
            foreach ($do_teaser as $src_name => $val) {
                $id = $option_basename . '-' . $src_name;
                echo '<div class="agp-vspaced_input">';
                echo "<label for='{$id}'>";
                $checked = $val ? ' checked="checked"' : '';
                $js_call = "agp_display_if('teaserdef-{$src_name}', '{$id}');agp_display_if('teaser_usage-{$src_name}', '{$id}');agp_display_if('teaser-pvt-{$src_name}', '{$id}');";
                echo "<input name='{$id}' type='checkbox' onclick=\"{$js_call}\" id='{$id}' value='1' {$checked} /> ";
                $display = scoper_display_otypes_or_source_name($src_name);
                printf(__("Enable teaser for %s", 'scoper'), $display);
                echo '</label><br />';
                $css_display = $do_teaser[$src_name] ? 'block' : 'none';
                $style = "style='margin-left: 1em;'";
                echo "<div id='teaser_usage-{$src_name}' style='display:{$css_display};'>";
                // loop through each object type (for current source) to provide a use_teaser checkbox
                foreach ($use_teaser as $src_otype => $teaser_setting) {
                    if ($src_name != scoper_src_name_from_src_otype($src_otype)) {
                        continue;
                    }
                    if (is_bool($teaser_setting)) {
                        $teaser_setting = intval($teaser_setting);
                    }
                    $id = str_replace(':', '_', $option_use_teaser . '-' . $src_otype);
                    echo '<div class="agp-vspaced_input">';
                    echo "<label for='{$id}' style='margin-left: 2em;'>";
                    $item_label_singular = $scoper_admin->interpret_src_otype($src_otype);
                    printf(__("%s:", 'scoper'), $item_label_singular);
                    echo "<select name='{$id}' id='{$id}'>";
                    $num_chars = defined('SCOPER_TEASER_NUM_CHARS') ? SCOPER_TEASER_NUM_CHARS : 50;
                    $captions = array(0 => __("no teaser", 'scoper'), 1 => __("fixed teaser (specified below)", 'scoper'), 'excerpt' => __("excerpt as teaser", 'scoper'), 'more' => __("excerpt or pre-more as teaser", 'scoper'), 'x_chars' => sprintf(__("excerpt, pre-more or first %s chars", 'scoper'), $num_chars));
                    foreach ($captions as $teaser_option_val => $teaser_caption) {
                        $selected = $teaser_setting == $teaser_option_val ? 'selected="selected"' : '';
                        echo "\n\t<option value='{$teaser_option_val}' {$selected}>{$teaser_caption}</option>";
                    }
                    echo '</select></label><br />';
                    // Checkbox option to skip teaser for anonymous users
                    $id = str_replace(':', '_', $option_logged_only . '-' . $src_otype);
                    echo "<span style='margin-left: 6em'>";
                    //echo( _ x( 'for:', 'teaser: anonymous, logged or both', 'scoper') );
                    echo __('for:', 'scoper');
                    echo "&nbsp;&nbsp;<label for='{$id}_logged'>";
                    $checked = !empty($logged_only[$src_otype]) && 'anon' == $logged_only[$src_otype] ? ' checked="checked"' : '';
                    echo "<input name='{$id}' type='radio' id='{$id}_logged' value='anon' {$checked} />";
                    echo "";
                    _e("anonymous", 'scoper');
                    echo '</label></span>';
                    // Checkbox option to skip teaser for logged users
                    echo "<span style='margin-left: 1em'><label for='{$id}_anon'>";
                    $checked = !empty($logged_only[$src_otype]) && 'anon' != $logged_only[$src_otype] ? ' checked="checked"' : '';
                    echo "<input name='{$id}' type='radio' id='{$id}_anon' value='1' {$checked} />";
                    echo "";
                    _e("logged", 'scoper');
                    echo '</label></span>';
                    // Checkbox option to do teaser for BOTH logged and anon users
                    echo "<span style='margin-left: 1em'><label for='{$id}_all'>";
                    $checked = empty($logged_only[$src_otype]) ? ' checked="checked"' : '';
                    echo "<input name='{$id}' type='radio' id='{$id}_all' value='0' {$checked} />";
                    echo "";
                    _e("both", 'scoper');
                    echo '</label></span>';
                    echo '</div>';
                }
                echo '</div>';
                if (empty($displayed_teaser_caption)) {
                    echo '<span class="rs-subtext">';
                    if ($ui->display_hints) {
                        _e('If content is blocked, display replacement text instead of hiding it completely.', 'scoper');
                        echo '<br />';
                        _e('<strong>Note:</strong> the prefix and suffix settings below will always be applied unless the teaser mode is "no teaser".', 'scoper');
                    }
                    echo '</span>';
                    $displayed_teaser_caption = true;
                }
                // provide hide private (instead of teasing) checkboxes for each pertinent object type
                echo '<br /><br />';
                $display_style = $do_teaser[$src_name] ? '' : "style='display:none;'";
                echo "<div id='teaser-pvt-{$src_name}' {$display_style}>";
                $type_caption = $scoper_admin->interpret_src_otype('post:post');
                printf(__("Hide private %s (instead of teasing)", 'scoper'), $type_caption);
                // back compat for existing translations
                echo '<br />';
                echo '<div style="margin-left: 2em">';
                foreach ($hide_private as $src_otype => $teaser_setting) {
                    if ($src_name != scoper_src_name_from_src_otype($src_otype)) {
                        continue;
                    }
                    $id = str_replace(':', '_', $option_hide_private . '-' . $src_otype);
                    echo "<label for='{$id}'>";
                    $checked = $teaser_setting ? ' checked="checked"' : '';
                    echo "<input name='{$id}' type='checkbox' id='{$id}' value='1' {$checked} /> ";
                    echo $scoper_admin->interpret_src_otype($src_otype);
                    echo '</label><br />';
                }
                echo '</div>';
                echo '<span class="rs-subtext">';
                if ($ui->display_hints) {
                    _e('Hide private content completely, while still showing a teaser for content which is published with restrictions.  <strong>Note:</strong> Private posts hidden in this way will reduce the total number of posts on their "page" of a blog listing.', 'scoper');
                }
                echo '</span>';
                echo '</div>';
            }
            // end foreach source's do_teaser setting
            ?>

	</div>
	<?php 
            // now draw the teaser replacement / prefix / suffix input boxes
            $user_suffixes = array('_anon', '');
            $item_actions = array('name' => array('prepend', 'append'), 'content' => array('replace', 'prepend', 'append'), 'excerpt' => array('replace', 'prepend', 'append'));
            $items_display = array('name' => __('name', 'scoper'), 'content' => __('content', 'scoper'), 'excerpt' => __('excerpt', 'scoper'));
            $actions_display = array('replace' => __('replace with (if using fixed teaser, or no excerpt available):', 'scoper'), 'prepend' => __('prefix with:', 'scoper'), 'append' => __('suffix with:', 'scoper'));
            // first determine all src:otype keys
            $src_otypes = array();
            foreach ($user_suffixes as $anon) {
                foreach ($item_actions as $item => $actions) {
                    foreach ($actions as $action) {
                        $ui->all_otype_options[] = "teaser_{$action}_{$item}{$anon}";
                        if (!empty($ui->def_otype_options["teaser_{$action}_{$item}{$anon}"])) {
                            $src_otypes = array_merge($src_otypes, $ui->def_otype_options["teaser_{$action}_{$item}{$anon}"]);
                        }
                    }
                }
            }
            $last_src_name = '';
            foreach (array_keys($src_otypes) as $src_otype) {
                $src_name = scoper_src_name_from_src_otype($src_otype);
                if ($src_name != $last_src_name) {
                    if ($last_src_name) {
                        echo '</div>';
                    }
                    $last_src_name = $src_name;
                    $css_display = $do_teaser[$src_name] ? 'block' : 'none';
                    echo "<div id='teaserdef-{$src_name}' style='display:{$css_display}; margin-top: 2em;'>";
                }
                $item_label_singular = $scoper_admin->interpret_src_otype($src_otype);
                // separate input boxes to specify teasers for anon users and unpermitted logged users
                foreach ($user_suffixes as $anon) {
                    $user_descript = $anon ? __('anonymous users', 'scoper') : __('logged users', 'scoper');
                    echo '<strong>';
                    printf(__('%1$s Teaser Text (%2$s):', 'scoper'), $item_label_singular, $user_descript);
                    echo '</strong>';
                    echo '<ul class="rs-textentries">';
                    // items are name, content, excerpt
                    foreach ($item_actions as $item => $actions) {
                        echo '<li>' . $items_display[$item] . ':';
                        echo '<ul>';
                        // actions are prepend / append / replace
                        foreach ($actions as $action) {
                            $option_name = "teaser_{$action}_{$item}{$anon}";
                            if (!($opt_vals = scoper_get_option($option_name, $sitewide, $customize_defaults))) {
                                $opt_vals = array();
                            }
                            $ui->all_otype_options[] = $option_name;
                            if (!empty($ui->def_otype_options["teaser_{$action}_{$item}{$anon}"])) {
                                $opt_vals = array_merge($ui->def_otype_options[$option_name], $opt_vals);
                            }
                            if (isset($opt_vals[$src_otype])) {
                                $val = htmlspecialchars($opt_vals[$src_otype]);
                                $id = str_replace(':', '_', $option_name . '-' . $src_otype);
                                echo "<li><label for='{$id}'>";
                                echo $actions_display[$action];
                                ?>

	<input name="<?php 
                                echo $id;
                                ?>
" type="text" style="width: 95%" id="<?php 
                                echo $id;
                                ?>
" value="<?php 
                                echo $val;
                                ?>
" />
	</label><br /></li>
	<?php 
                            }
                            // endif isset($opt_vals)
                        }
                        // end foreach actions
                        echo '</ul></li>';
                    }
                    // end foreach item_actions
                    echo "</ul><br />";
                }
                // end foreach user_suffixes
            }
            // end foreach src_otypes
            echo '</div>';
        }
        // endif any default otype_options for do_teaser
        ?>

	</td>
	</tr>
<?php 
    }
    // any options accessable in this section
    if (!defined('RVY_VERSION')) {
        echo '<tr><td colspan="2"><div class="rs-optionhint"><p style="margin-left:4em;text-indent:-3.5em">&nbsp;';
        printf(__('<span class="rs-green"><strong>Idea:</strong></span> For Scheduled Revisions and Pending Revisions functionality that integrates with your RS Roles and Restrictions, install %1$s Revisionary%2$s, another %3$s Agapetry&nbsp;Creations%4$s plugin.', 'scoper'), "<a href='" . awp_plugin_info_url("revisionary") . "'>", '</a>', "<a href='http://agapetry.net'>", '</a>');
        echo '</p></div></td></tr>';
    }
    ?>

	
</table>

</div>
<?php 
    // ------------------------- END Features tab ---------------------------------
    // ------------------------- BEGIN Advanced tab ---------------------------------
    $tab = 'advanced';
    if (!empty($ui->form_options[$tab])) {
        ?>


<?php 
        echo "<div id='rs-advanced' style='clear:both;margin:0' class='rs-options agp_js_hide {$color_class}'>";
        if ($ui->display_hints) {
            echo '<div class="rs-optionhint">';
            _e("<strong>Note:</strong> for most installations, the default settings are fine.", 'scoper');
            echo '</div>';
        }
        ?>

<table class="<?php 
        echo $table_class;
        ?>
" id="rs-advanced_table">
<?php 
        $section = 'role_basis';
        if (!empty($ui->form_options[$tab][$section])) {
            ?>

	<tr valign="top">
	<th scope="row"><?php 
            echo $ui->section_captions[$tab][$section];
            // --- ROLE BASIS SECTION ---
            ?>

	</th><td>
	
	<?php 
            $hint = '';
            $ui->option_checkbox('enable_group_roles', $tab, $section, $hint, '');
            $hint = '';
            $ui->option_checkbox('enable_user_roles', $tab, $section, $hint, '');
            if (scoper_get_option('custom_user_blogcaps', $sitewide, $customize_defaults) || ScoperAdminLib::any_custom_caps_assigned()) {
                $hint = __('Some users created under older WP versions may have direct-assigned capabilities in addition to their blog-wide role assignment.  This setting does not enable or block that feature, but determines whether Role Scoper must account for it.  Disable when possible (capabilities unrelated to RS Role Definitions are irrelevant).', 'scoper');
                $ui->option_checkbox('custom_user_blogcaps', $tab, $section, $hint, '');
            }
            ?>

	
	</td></tr>
<?php 
        }
        // any options accessable in this section
        $section = 'page_structure';
        if (!empty($ui->form_options[$tab][$section])) {
            ?>

	<tr valign="top">
	<th scope="row"><?php 
            echo $ui->section_captions[$tab][$section];
            // --- PAGE STRUCTURE SECTION ---
            ?>
</th><td>

	<?php 
            $id = 'lock_top_pages';
            $ui->all_options[] = $id;
            $current_setting = strval(scoper_get_option($id, $sitewide, $customize_defaults));
            // force setting and corresponding keys to string, to avoid quirks with integer keys
            echo $ui->option_captions['lock_top_pages'];
            $captions = array('author' => __('Page Authors, Editors and Administrators', 'scoper'), '' => __('Page Editors and Administrators', 'scoper'), '1' => __('Administrators', 'scoper'));
            foreach ($captions as $key => $value) {
                $key = strval($key);
                echo "<div style='margin: 0 0 0.5em 2em;'><label for='{$id}_{$key}'>";
                $checked = $current_setting === $key ? "checked='checked'" : '';
                echo "<input name='{$id}' type='radio' id='{$id}_{$key}' value='{$key}' {$checked} />";
                echo $value;
                echo '</label></div>';
            }
            echo '<span class="rs-subtext">';
            if ($ui->display_hints) {
                _e('Users who do not meet this site-wide role requirement may still be able to save and/or publish pages, but will not be able to publish a new page with a Page Parent setting of "Main Page".  Nor will they be able to move a currently published page from "Main Page" to a different Page Parent.', 'scoper');
            }
            echo '</span>';
            ?>


	</td></tr>
<?php 
        }
        // any options accessable in this section
        $section = 'user_profile';
        if (!empty($ui->form_options[$tab][$section])) {
            ?>

	<tr valign="top">
	<th scope="row"><?php 
            echo $ui->section_captions[$tab][$section];
            // --- USER PROFILE SECTION ---
            ?>
</th><td>
	
	<?php 
            $hint = '';
            $ui->option_checkbox('display_user_profile_groups', $tab, $section, $hint, '');
            $hint = '';
            $ui->option_checkbox('display_user_profile_roles', $tab, $section, $hint, '');
            ?>

		
	</td></tr>
<?php 
        }
        // any options accessable in this section
        $section = 'user_management';
        if (!empty($ui->form_options[$tab][$section])) {
            ?>

	<tr valign="top">
	<th scope="row"><?php 
            echo $ui->section_captions[$tab][$section];
            // --- USER MANAGEMENT SECTION ---
            ?>
</th><td>
	
	<?php 
            $hint = __('If enabled, prevents those with edit_users capability from editing a user with a higher level or assigning a role higher than their own.', 'scoper');
            $ui->option_checkbox('limit_user_edit_by_level', $tab, $section, $hint, '');
            ?>


	</td></tr>
<?php 
        }
        // any options accessable in this section
        $section = 'administrator_definition';
        if ($sitewide || !IS_MU_RS) {
            ?>

	<tr valign="top">
	<th scope="row"><?php 
            echo $ui->section_captions[$tab][$section];
            // --- ADMINISTRATOR DEFINITION SECTION ---
            ?>
</th><td>
	<?php 
            $default_cap = array('option' => 'manage_options', 'user' => 'edit_users', 'content' => 'activate_plugins');
            $name['content'] = __('Content Administrator', 'scoper');
            $name['user'] = __('User Administrator', 'scoper');
            $name['option'] = __('Option Administrator', 'scoper');
            $descript['content'] = __('RS never applies restricting or enabling content filters', 'scoper');
            $descript['user'] = __('RS allows full editing of all user groups and scoped roles / restrictions', 'scoper');
            $descript['option'] = __('Can edit Role Scoper options', 'scoper');
            _e('Role Scoper internally checks the following capabilities for content and role administration.  By default, these capabilities are all contained in the Administrator role only.  You can use the Capability Manager plugin to split/overlap them among different roles as desired.', 'scoper');
            echo '<table id="rs-admin-info" style="max-width: 80em">' . '<tr>' . '<th style="font-weight:normal">' . __('Administrator Type', 'scoper') . '</th>' . '<th style="font-weight:normal">' . __('Required Capability', 'scoper') . '</th>' . '<th width="80%" style="font-weight:normal">' . __awp('Description') . '</th>' . '</tr>';
            foreach (array_keys($name) as $admin_type) {
                $constant_name = 'SCOPER_' . strtoupper($admin_type) . '_ADMIN_CAP';
                $cap_name = defined($constant_name) ? constant($constant_name) : $default_cap[$admin_type];
                echo '<tr>' . '<td><strong>' . $name[$admin_type] . '</strong></td>' . '<td>' . $cap_name . '</td>' . '<td width="60%" >' . $descript[$admin_type] . '</td>' . '</tr>';
                if ('content' == $admin_type && $cap_name != $default_cap['content']) {
                    $custom_content_admin_cap = true;
                }
            }
            echo '</table>';
            _e('Each administrator type\'s <strong>capability can be modified</strong> by adding any of the following define statements to your wp-config.php:', 'scoper');
            echo '<div style="margin:0 10em 2em 10em">';
            echo "<code>define( 'SCOPER_CONTENT_ADMIN_CAP', 'your_content_capname' );</code>";
            echo '<br />';
            echo "<code>define( 'SCOPER_USER_ADMIN_CAP', 'your_user_capname' );</code>";
            echo '<br />';
            echo "<code>define( 'SCOPER_OPTION_ADMIN_CAP', 'your_option_capname' );</code>";
            echo '</div>';
            _e('For example, by using Capability Manager to add a custom capability such as <strong>administer_all_content</strong> to certain WordPress roles, you could mirror that setting in the SCOPER_CONTENT_ADMIN_CAP definition to ensure that those users are never content-restricted by Role Scoper.', 'scoper');
            ?>

	</td></tr>
<?php 
        }
        // any options accessable in this section
        $section = 'limited_editing_elements';
        if (!empty($ui->form_options[$tab][$section])) {
            ?>

	<tr valign="top">
	<th scope="row"><?php 
            echo $ui->section_captions[$tab][$section];
            // --- LIMITED EDITING ELEMENTS SECTION ---
            ?>
</th><td>
	
	<?php 
            if (in_array('admin_css_ids', $ui->form_options[$tab][$section])) {
                ?>

		<div class="agp-vspaced_input">
		<?php 
                if ($ui->display_hints) {
                    echo '<div class="agp-vspaced_input">';
                    _e('Remove Edit Form elements with these html IDs from users who do not have full editing capabilities for the post/page. Separate with&nbsp;;', 'scoper');
                    echo '</div>';
                }
                ?>

		</div>
		<?php 
                $option_name = 'admin_css_ids';
                if (isset($ui->def_otype_options[$option_name])) {
                    if (!($opt_vals = scoper_get_option($option_name, $sitewide, $customize_defaults))) {
                        $opt_vals = array();
                    }
                    $opt_vals = array_merge($ui->def_otype_options[$option_name], $opt_vals);
                    $ui->all_otype_options[] = $option_name;
                    $sample_ids = array();
                    // note: 'post:post' otype option is used for all non-page types
                    $sample_ids['post:post'] = '<span id="rs_sample_ids_post:post" class="rs-gray" style="display:none">' . 'rs_private_post_reader; rs_post_contributor; categorydiv; password-span; slugdiv; authordiv; commentstatusdiv; postcustom; trackbacksdiv; tagsdiv-post_tag; postexcerpt; revisionsdiv; visibility; misc-publishing-actions; edit-slug-box' . '</span>';
                    $sample_ids['post:page'] = '<span id="rs_sample_ids_post:page" class="rs-gray" style="display:none">' . 'rs_private_page_reader; rs_page_contributor; rs_page_associate; password-span; pageslugdiv; pageauthordiv; pagecommentstatusdiv; pagecustomdiv; pageparentdiv; revisionsdiv; visibility; misc-publishing-actions; edit-slug-box' . '</span>';
                    foreach ($opt_vals as $src_otype => $val) {
                        $id = str_replace(':', '_', $option_name . '-' . $src_otype);
                        $display = $scoper_admin->interpret_src_otype($src_otype, 'singular_name');
                        echo '<div class="agp-vspaced_input">';
                        echo '<span class="rs-vtight">';
                        printf(__('%s Edit Form HTML IDs:', 'scoper'), $display);
                        ?>

		<label for="<?php 
                        echo $id;
                        ?>
">
		<input name="<?php 
                        echo $id;
                        ?>
" type="text" size="45" style="width: 95%" id="<?php 
                        echo $id;
                        ?>
" value="<?php 
                        echo $val;
                        ?>
" />
		</label>
		</span>
		<br />
		<?php 
                        if (isset($sample_ids[$src_otype])) {
                            $js_call = "agp_set_display('rs_sample_ids_{$src_otype}', 'inline');";
                            printf(__('%1$s sample IDs:%2$s %3$s', 'scoper'), "<a href='javascript:void(0)' onclick=\"{$js_call}\">", '</a>', $sample_ids[$src_otype]);
                        }
                        ?>

		</div>
		<?php 
                    }
                    // end foreach optval
                }
                // endif any default admin_css_ids options
                ?>

		
		<br />
	<?php 
            }
            ?>

		
	
	<?php 
            if (in_array('hide_non_editor_admin_divs', $ui->form_options[$tab][$section])) {
                $id = 'hide_non_editor_admin_divs';
                $ui->all_options[] = $id;
                $current_setting = strval(scoper_get_option($id, $sitewide, $customize_defaults));
                // force setting and corresponding keys to string, to avoid quirks with integer keys
                ?>

		<div class="agp-vspaced_input">
		<?php 
                _e('Specified element IDs also require the following site-wide Role:', 'scoper');
                $admin_caption = !empty($custom_content_admin_cap) ? __('Content Administrator', 'scoper') : __awp('Administrator');
                $captions = array('0' => __('no requirement', 'scoper'), '1' => __('Contributor / Author / Editor', 'scoper'), 'author' => __('Author / Editor', 'scoper'), 'editor' => __awp('Editor'), 'admin_content' => __('Content Administrator', 'scoper'), 'admin_user' => __('User Administrator', 'scoper'), 'admin_option' => __('Option Administrator', 'scoper'));
                foreach ($captions as $key => $value) {
                    $key = strval($key);
                    echo "<div style='margin: 0 0 0.5em 2em;'><label for='{$id}_{$key}'>";
                    $checked = $current_setting === $key ? "checked='checked'" : '';
                    echo "<input name='{$id}' type='radio' id='{$id}_{$key}' value='{$key}' {$checked} />";
                    echo $value;
                    echo '</label></div>';
                }
                ?>

		<span class="rs-subtext">
		<?php 
                if ($ui->display_hints) {
                    _e('Note: The above roles are type-specific RS roles (for the object type involved) which must be contained in a user\'s site-wide WordPress role.', 'scoper');
                }
                ?>

		</span>
		</div>
	<?php 
            }
            ?>

		
	</td>
	</tr>
<?php 
        }
        // any options accessable in this section
        $section = 'role_assignment_interface';
        if (!empty($ui->form_options[$tab][$section])) {
            ?>

	<tr valign="top">
	<th scope="row"><?php 
            echo $ui->section_captions[$tab][$section];
            // --- ROLE ASSIGNMENT INTERFACE SECTION ---
            ?>
</th><td>
	
	<?php 
            $otype_caption = __('Limit eligible users for %s-specific editing roles', 'scoper');
            $hint = __('Role Scoper can enable any user to edit a post or page you specify, regardless of their site-wide WordPress role.  If that\'s not a good thing, check above options to require basic editing capability blog-wide or category-wide.', 'scoper');
            $ui->otype_option_checkboxes('limit_object_editors', $otype_caption, $tab, $section, $hint, '<br /><br />', array('label_property' => 'singular_name'));
            $hint = __('In the Edit Post/Edit Page roles tabs, decorate user/group name with colors and symbols if they have the role implicitly via group, general role, category role, or a superior post/page role.', 'scoper');
            $ui->option_checkbox('indicate_blended_roles', $tab, $section, $hint, '<br />');
            $hint = __('Display introductory descriptions at the top of various role assignment / definition screens.', 'scoper');
            $ui->option_checkbox('display_hints', $tab, $section, $hint, '<br />');
            $hint = __('Accept entry of user names or IDs via comma-separated text instead of individual checkboxes.', 'scoper');
            $ui->option_checkbox('user_role_assignment_csv', $tab, $section, $hint, '');
            ?>

		
	</td></tr>
<?php 
        }
        // any options accessable in this section
        $section = 'custom_columns';
        if (!empty($ui->form_options[$tab][$section])) {
            ?>

	<tr valign="top">
	<th scope="row"><?php 
            echo $ui->section_captions[$tab][$section];
            // --- ROLE ASSIGNMENT INTERFACE SECTION ---
            ?>
</th><td>
	
	<?php 
            $hint = '';
            $otype_caption = __('Restrictions column in Edit %s listing', 'scoper');
            $ui->otype_option_checkboxes('restrictions_column', $otype_caption, $tab, $section, $hint, '<br />');
            $otype_caption = __('Term Roles column in Edit %s listing', 'scoper');
            $ui->otype_option_checkboxes('term_roles_column', $otype_caption, $tab, $section, $hint, '<br />');
            $otype_caption = __('Object Roles column in Edit %s listing', 'scoper');
            $ui->otype_option_checkboxes('object_roles_column', $otype_caption, $tab, $section, $hint, '<br />');
            ?>

		
	</td></tr>
<?php 
        }
        // any options accessable in this section
        $section = 'additional_object_roles';
        if (!empty($ui->form_options[$tab][$section])) {
            $post_types = array_diff(get_post_types(array('public' => true)), array('attachment'));
            foreach ($post_types as $_type) {
                $objscope_equiv_roles["rs_{$_type}_reader"] = "rs_private_{$_type}_reader";
                $objscope_equiv_roles["rs_{$_type}_author"] = "rs_{$_type}_editor";
            }
            if (IS_MU_RS) {
                // apply option scope filtering for mu
                foreach (array_keys($objscope_equiv_roles) as $role_name) {
                    if (!in_array($role_name . '_role_objscope', $ui->form_options[$tab][$section])) {
                        $objscope_equiv_roles = array_diff_key($objscope_equiv_roles, array($role_name => true));
                    }
                }
            }
            if (!empty($objscope_equiv_roles)) {
                ?>

		<?php 
                foreach ($objscope_equiv_roles as $role_handle => $equiv_role_handle) {
                    $ui->all_options[] = "{$role_handle}_role_objscope";
                }
                ?>

		<tr valign="top">
		<th scope="row"><?php 
                echo $ui->section_captions[$tab][$section];
                ?>
</th>
		<td>
		<?php 
                foreach ($objscope_equiv_roles as $role_handle => $equiv_role_handle) {
                    $id = "{$role_handle}_role_objscope";
                    $checked = scoper_get_option($id, $sitewide, $customize_defaults) ? "checked='checked'" : '';
                    echo '<div class="agp-vspaced_input">';
                    echo "<label for='{$id}'>";
                    echo "<input name='{$id}' type='checkbox' id='{$id}' value='1' {$checked} /> ";
                    if (in_array($role_handle, array('rs_post_reader', 'rs_post_author'))) {
                        printf(__('%1$s (normally equivalent to %2$s)', 'scoper'), $scoper->role_defs->get_display_name($role_handle), $scoper->role_defs->get_display_name($equiv_role_handle));
                    } else {
                        echo $scoper->role_defs->get_display_name($role_handle);
                    }
                    echo '</label></div>';
                }
                ?>

		<span class="rs-subtext">
		<?php 
                if ($ui->display_hints) {
                    _e('By default, the above roles are not available for object-specific assignment because another role is usually equivalent. However, the distinctions may be useful if you propagate roles to sub-Pages, set Default Roles or customize RS Role Definitions.', 'scoper');
                    echo '<br /><br />';
                    _e('Note: Under the default configuration, the tabs labeled "Reader" in the Post/Page Edit Form actually assign the corresponding Private Reader role.', 'scoper');
                }
                ?>

		</span>
		</td></tr>
	
	<?php 
            }
            // any objscope_equiv_roles options available in this section
            ?>
	
		
<?php 
        }
        // any options accessable in this section
        ?>
	


</table>
</div>

<?php 
    }
    // any options accessable in this tab
    ?>
	


<?php 
    // ------------------------- BEGIN Realm tab ---------------------------------
    $tab = 'realm';
    if (!empty($ui->form_options[$tab])) {
        ?>

<?php 
        echo "<div id='rs-realm' style='clear:both;margin:0' class='rs-options agp_js_hide {$color_class}'>";
        if ($ui->display_hints) {
            echo '<div class="rs-optionhint">';
            _e("These <strong>optional</strong> settings allow advanced users to adjust Role Scoper's sphere of influence. For most installations, the default settings are fine.", 'scoper');
            echo '</div>';
        }
        ?>


<table class="<?php 
        echo $table_class;
        ?>
" id="rs-realm_table">

<?php 
        $section_alias = 'term_object_scopes';
        if (!empty($ui->form_options[$tab][$section_alias])) {
            ?>



	<tr valign="top">
	<th scope="row"><?php 
            // --- TAXONOMY / OBJECT TYPE USAGE SECTION ---
            $section = 'taxonomy_usage';
            echo $ui->section_captions[$tab][$section];
            echo '<br />';
            ?>
</th><td>
	<?php 
            // note: update_wp_taxonomies gets special handling in submitee.php, doesn't need to be included in $ui->all_options array
            global $wp_taxonomies;
            global $scoper_default_options;
            _e('Specify which WordPress Taxonomies can have Restrictions and Roles:', 'scoper');
            echo '<br />';
            $registered = array();
            $registered['object'] = get_post_types(array());
            $registered['term'] = get_taxonomies(array());
            $public = array();
            $public['object'] = get_post_types(array('public' => true));
            $public['term'] = get_taxonomies(array('public' => true));
            $scopes = array('term', 'object');
            foreach ($scopes as $scope) {
                if ('object' == $scope) {
                    ?>
</td></tr>
<?php 
                    $section = 'post_type_usage';
                    $option_name = 'use_post_types';
                    ?>
	<tr valign="top">
	<th scope="row">
<?php 
                    echo $ui->section_captions[$tab][$section];
                    ?>
</th><td>
<?php 
                    _e('Specify which Post Types can have Restrictions and Roles:', 'scoper');
                } else {
                    // end if loop iteration is for object scope
                    $option_name = 'use_taxonomies';
                }
                if (in_array('use_term_roles', $ui->form_options[$tab][$section_alias])) {
                    // use_object_types follow option scope of use_term_roles
                    $ui->all_options[] = $option_name;
                    if (isset($scoper_default_options[$option_name])) {
                        if (!($opt_vals = scoper_get_option($option_name, $sitewide, $customize_defaults))) {
                            $opt_vals = array();
                        }
                        $opt_vals = array_merge($scoper_default_options[$option_name], $opt_vals);
                        foreach ($opt_vals as $key => $val) {
                            if (!$key) {
                                continue;
                            }
                            $id = $option_name . '-' . $key;
                            ?>

						
						<?php 
                            // nav menu and link category are currently governed by "Term Scope" setting only, so just set a hidden enable here
                            if (in_array($key, array('nav_menu', 'link_category'))) {
                                ?>

							<input name="<?php 
                                echo $id;
                                ?>
" type="hidden" id="<?php 
                                echo $id;
                                ?>
" value="1" />
						<?php 
                            } else {
                                ?>

							<div class="agp-vspaced_input">
							<label for="<?php 
                                echo $id;
                                ?>
" title="<?php 
                                echo $key;
                                ?>
">
							
							<input name="<?php 
                                echo $id;
                                ?>
" type="checkbox" id="<?php 
                                echo $id;
                                ?>
" value="1" <?php 
                                checked('1', $val);
                                ?>
 />
							
							<?php 
                                if (TERM_SCOPE_RS == $scope) {
                                    if ($tx = get_taxonomy($key)) {
                                        $display_name = $tx->labels->name;
                                    } else {
                                        $display_name = '';
                                    }
                                } else {
                                    if ($type_obj = get_post_type_object($key)) {
                                        $display_name = $type_obj->labels->name;
                                    } else {
                                        $display_name = '';
                                    }
                                }
                                if (!$display_name) {
                                    $display_name = $key;
                                }
                                if (!isset($public[$scope][$key])) {
                                    if (isset($registered[$scope][$key])) {
                                        $display_name .= '<span class="rs-warning"> <big>*</big></span>';
                                        $any_private_types = true;
                                    } else {
                                        $display_name .= '<span class="rs-warning"> <big>**</big></span>';
                                        $any_unregistered_types = true;
                                    }
                                }
                                echo $display_name;
                                echo '</label></div>';
                            }
                            // displaying checkbox UI
                        }
                        // end foreach src_otype
                    }
                    // endif default option isset
                }
                // endif displaying this option in form
                if (MULTISITE) {
                    $link_open = $link_close = '';
                } else {
                    $link_open = "<a href='admin.php?page=rs-general_roles'>";
                    $link_close = '</a>';
                }
                if (!empty($any_private_types)) {
                    $msg = 'term' == $scope ? __('<big>*</big> = private type, filtering may not be valid', 'scoper') : __('<big>*</big> = private taxonomy, filtering may not be valid', 'scoper');
                    echo '<div class="rs-warning">' . $msg . '</div><br />';
                    $any_private_types = false;
                }
                if (!empty($any_unregistered_types)) {
                    $msg = __('<big>**</big> = currently unregistered, corresponding plugin may be deactivated', 'scoper');
                    echo '<div class="rs-warning">' . $msg . '</div><br />';
                    $any_unregistered_types = false;
                }
                if ('term' == $scope) {
                    if (get_taxonomies(array('_builtin' => false, 'public' => true))) {
                        echo '<div>';
                        printf(__('<strong>NOTE:</strong> Non-Administrators need a %1$sTaxonomy-specific Role assignment%2$s to manage Custom Taxonomies selected here.', 'scoper'), $link_open, $link_close);
                        echo '</div>';
                    }
                } else {
                    if (get_post_types(array('_builtin' => false, 'public' => true))) {
                        echo '<div>';
                        printf(__('<strong>NOTE:</strong> Non-Administrators need a %1$sType-specific Role assignment%2$s to manage Custom Post Types selected here.', 'scoper'), $link_open, $link_close);
                        echo '</div><br />';
                    }
                }
            }
            // end foreach scope
            if (!defined('SCOPER_EARLY_INIT')) {
                echo '<div>';
                _e('<strong>NOTE:</strong> Role Scoper is operating in late-initialization mode, for compatibility with plugins which register taxonomies or post types on the "init" hook without specifying early execution priority.  If other plugins internally query posts (or post editing capabilities) on the "init" action, those results will not be filtered.  In that event, find a way to register your taxonomies/post types earlier and add the following to wp-config.php:', 'scoper');
                echo '<div id="rs-type-tx-help">';
                echo "<pre>&nbsp;&nbsp;define( 'SCOPER_EARLY_INIT', true );</pre>";
                echo '</div>';
                echo '</div>';
            }
            ?>

	</td>
	</tr>


	<tr valign="top">
	<th scope="row"><?php 
            // --- TERM SCOPE SECTION ---
            $section = 'term_scope';
            echo $ui->section_captions[$tab][$section];
            echo '<br /><span style="font-size: 0.9em; font-style: normal; font-weight: normal">(&nbsp;<a href="#scoper_notes">' . __('see notes', 'scoper') . '</a>&nbsp;)</span>';
            ?>
</th><td>
	<?php 
            // note: update_wp_taxonomies gets special handling in submitee.php, doesn't need to be included in $ui->all_options array
            global $wp_taxonomies;
            _e('Specify available Term Restrictions and Roles, for each object type and taxonomy:', 'scoper');
            echo '<br />&nbsp;&nbsp;&nbsp;&nbsp;';
            _e('<b>Note:</b> Taxonomy Usage must also be enabled above', 'scoper');
            echo '<br />';
            $scopes = array('term', 'object');
            foreach ($scopes as $scope) {
                if ('object' == $scope) {
                    ?>
</td></tr>
<?php 
                    $section = 'object_scope';
                    ?>
	<tr valign="top">
	<th scope="row">
<?php 
                    // --- TERM / OBJECT SCOPE SECTION ---
                    echo $ui->section_captions[$tab][$section];
                    ?>
</th><td>
<?php 
                    _e('Specify whether Restrictions and Roles can be set for individual Objects:', 'scoper');
                    echo '<br />&nbsp;&nbsp;&nbsp;&nbsp;';
                    _e('<b>Note:</b> Post Type Usage must also be enabled above', 'scoper');
                } else {
                    // end if loop iteration is for object scope
                    $section = 'term_scope';
                }
                $option_name = "use_{$scope}_roles";
                if (in_array('use_term_roles', $ui->form_options[$tab][$section_alias])) {
                    // use_object_roles follow option scope of use_term_roles
                    $ui->all_otype_options[] = $option_name;
                    if (isset($ui->def_otype_options[$option_name])) {
                        if (!($opt_vals = scoper_get_option($option_name, $sitewide, $customize_defaults))) {
                            $opt_vals = array();
                        }
                        if ('use_term_roles' == $option_name) {
                            foreach (array_keys($ui->def_otype_options[$option_name]) as $src_otype) {
                                if (isset($opt_vals[$src_otype])) {
                                    $opt_vals[$src_otype] = array_merge($ui->def_otype_options[$option_name][$src_otype], $opt_vals[$src_otype]);
                                } else {
                                    $opt_vals[$src_otype] = $ui->def_otype_options[$option_name][$src_otype];
                                }
                            }
                        } else {
                            $opt_vals = array_merge($ui->def_otype_options[$option_name], $opt_vals);
                        }
                        foreach ($opt_vals as $src_otype => $val) {
                            if (TERM_SCOPE_RS == $scope) {
                                echo '<div style="margin-bottom: 2em">';
                                foreach (array_keys($opt_vals[$src_otype]) as $taxonomy) {
                                    $id = str_replace(':', '_', $option_name . '-' . $src_otype . '-' . $taxonomy);
                                    ?>

								<div class="agp-vspaced_input">
								<label for="<?php 
                                    echo $id;
                                    ?>
" title="<?php 
                                    echo $taxonomy;
                                    ?>
">
								<input name="<?php 
                                    echo $id;
                                    ?>
" type="checkbox" id="<?php 
                                    echo $id;
                                    ?>
" value="1" <?php 
                                    checked('1', $val[$taxonomy]);
                                    ?>
 />
								<?php 
                                    $tx_display = $scoper->taxonomies->member_property($taxonomy, 'labels', 'name');
                                    if (!$tx_display) {
                                        $tx_display = $taxonomy;
                                    }
                                    $display_name_plural = $scoper_admin->interpret_src_otype($src_otype);
                                    //printf( _ x('%1$s (for %2$s)', 'Category (for Posts)', 'scoper'), $tx_display, $display_name_plural );
                                    printf(__('%1$s (for %2$s)', 'scoper'), $tx_display, $display_name_plural);
                                    if (!$scoper->taxonomies->member_property($taxonomy, 'requires_term')) {
                                        echo '* ';
                                        $any_loose_taxonomy = true;
                                    }
                                    echo '</label></div>';
                                }
                                echo '</div>';
                            } else {
                                $id = str_replace(':', '_', $option_name . '-' . $src_otype);
                                ?>

							<div class="agp-vspaced_input">
							<label for="<?php 
                                echo $id;
                                ?>
" title="<?php 
                                echo $src_otype;
                                ?>
">
							<input name="<?php 
                                echo $id;
                                ?>
" type="checkbox" id="<?php 
                                echo $id;
                                ?>
" value="1" <?php 
                                checked('1', $val);
                                ?>
 />
							<?php 
                                echo $scoper_admin->interpret_src_otype($src_otype);
                                echo '</label></div>';
                            }
                        }
                        // end foreach src_otype
                    }
                    // endif default option isset
                }
                // endif displaying this option in form
                if ('term' == $scope) {
                    if (!empty($any_loose_taxonomy)) {
                        echo "<span class='rs-gray'>" . __('* = Role Assignment only (no Restrictions)', 'scoper') . '</span>';
                    }
                }
            }
            // end foreach scope
            ?>

	</td>
	</tr>
<?php 
        }
        // any options accessable in this section
        $section = 'access_types';
        if (!empty($ui->form_options[$tab][$section])) {
            ?>

	<tr valign="top">
	<th scope="row"><?php 
            // --- ACCESS TYPES SECTION ---
            echo $ui->section_captions[$tab][$section];
            ?>
</th>
	<td>
	<?php 
            // note: disabled_access_types option gets special handling in submitee.php, doesn't need to be included in $ui->all_options array
            _e('Apply Roles and Restrictions for:', 'scoper');
            echo '<br />';
            $topic = "access_types";
            $opt_vals = scoper_get_option("disabled_{$topic}", $sitewide, $customize_defaults);
            $all = implode(',', $scoper->access_types->get_all_keys());
            echo "<input type='hidden' name='all_access_types' value='{$all}' />";
            foreach ($scoper->access_types->get_all() as $access_name => $access_type) {
                $id = $topic . '-' . $access_name;
                $val = empty($opt_vals[$access_name]);
                ?>

	<div class="agp-vspaced_input">
	<label for="<?php 
                echo $id;
                ?>
">
	<input name="<?php 
                echo $id;
                ?>
[]" type="checkbox" id="<?php 
                echo $id;
                ?>
" value="<?php 
                echo $access_name;
                ?>
" <?php 
                checked('1', $val);
                ?>
 />
	<?php 
                if ('front' == $access_name) {
                    _e('Viewing content (front-end)', 'scoper');
                } elseif ('admin' == $access_name) {
                    _e('Editing and administering content (admin)', 'scoper');
                } else {
                    echo $access_type->labels->name;
                }
                echo '</label></div>';
            }
            // end foreach access types
            ?>

	<br />
	</td></tr>
<?php 
        }
        // any options accessable in this section
        ?>


<?php 
        // NOTE: Access Types section (for disabling data sources / otypes individually) was removed due to complication with hardway filtering.
        // For last source code, see 1.0.0-rc8
        ?>


</table>

<?php 
        echo '<h4 style="margin-bottom:0.1em"><a name="scoper_notes"></a>' . __("Notes", 'scoper') . ':</h4><ul class="rs-notes">';
        echo '<li>';
        _e('The &quot;Post Tag&quot; taxonomy cannot be used to define restrictions because tags are not mandatory. For most installations, categories are a better mechanism to define roles. Note that <strong>Role Scoper does not filter tag storage</strong> based on the editing user\'s access.  As with any other custom-defined taxonomy, use this option at your own discretion.', 'scoper');
        echo '</li>';
        echo '</ul>';
        echo '</div>';
    }
    // any options accessable in this tab
    // ------------------------- END Realms tab ---------------------------------
    if (!empty($ui->form_options['rs_role_definitions'])) {
        // RS Role Definitions Tab
        include dirname(__FILE__) . '/role_definition.php';
        scoper_display_rs_roledefs(array('bgcolor_class' => $color_class, 'sitewide' => $sitewide, 'customize_defaults' => $customize_defaults));
        // WP Role Definitions Tab
        include dirname(__FILE__) . '/role_definition_wp.php';
        scoper_display_wp_roledefs(array('bgcolor_class' => $color_class));
    }
    // ------------------------- BEGIN Option Scope tab ---------------------------------
    $tab = 'optscope';
    if ($sitewide) {
        ?>

<?php 
        echo "<div id='rs-optscope' style='clear:both;margin:0' class='rs-options agp_js_hide {$color_class}'>";
        if ($ui->display_hints) {
            echo '<div class="rs-optionhint">';
            _e("Specify which Role Scoper Options should be applied site-wide.", 'scoper');
            echo '</div><br />';
        }
        echo '<ul>';
        $all_movable_options = array();
        $option_scope_stamp = __('network-wide control of "%s"', 'scoper');
        foreach ($available_form_options as $tab_name => $sections) {
            echo '<li>';
            $explanatory_caption = __('Selected options will be controlled network-wide via <strong>Super Admin > Role Options</strong>; unselected options can be set per-site via <strong>Roles > Options</strong>', 'scoper');
            if (isset($ui->tab_captions[$tab_name])) {
                $tab_caption = $ui->tab_captions[$tab_name];
            } else {
                $tab_caption = $tab_name;
            }
            echo '<div style="margin:1em 0 1em 0">';
            if ($ui->display_hints) {
                printf(__('<span class="rs-h3text rs-blue">%1$s</span> (%2$s)', 'scoper'), $tab_caption, $explanatory_caption);
            } else {
                echo $tab_caption;
            }
            echo '</div>';
            echo '<ul style="margin-left:2em">';
            foreach ($sections as $section_name => $option_names) {
                if (empty($sections[$section_name])) {
                    continue;
                }
                echo '<li><strong>';
                if (isset($ui->section_captions[$tab_name][$section_name])) {
                    echo $ui->section_captions[$tab_name][$section_name];
                } else {
                    _e($section_name);
                }
                echo '</strong><ul style="margin-left:2em">';
                foreach ($option_names as $option_name) {
                    if ($option_name && $ui->option_captions[$option_name]) {
                        $all_movable_options[] = $option_name;
                        echo '<li>';
                        $disabled = in_array($option_name, array('file_filtering', 'mu_sitewide_groups')) ? "disabled='disabled'" : '';
                        $id = "{$option_name}_sitewide";
                        $val = isset($scoper_options_sitewide[$option_name]);
                        echo "<label for='{$id}'>";
                        echo "<input name='rs_options_sitewide[]' type='checkbox' id='{$id}' value='{$option_name}' {$disabled} ";
                        checked('1', $val);
                        echo " />";
                        printf($option_scope_stamp, $ui->option_captions[$option_name]);
                        echo '</label></li>';
                    }
                }
                echo '</ul>';
            }
            echo '</ul><br /><hr />';
        }
        echo '</ul>';
        echo '</div>';
        $all_movable_options = implode(',', $all_movable_options);
        echo "<input type='hidden' name='rs_all_movable_options' value='{$all_movable_options}' />";
    }
    // any options accessable in this tab
    // ------------------------- END Option Scope tab ---------------------------------
    // this was required for Access Types section, which was removed
    //$all = implode(',', $all_otypes);
    //echo "<input type='hidden' name='all_object_types' value='$all' />";
    $ui->all_options = implode(',', $ui->all_options);
    $ui->all_otype_options = implode(',', array_unique($ui->all_otype_options));
    echo "<input type='hidden' name='all_options' value='{$ui->all_options}' />";
    echo "<input type='hidden' name='all_otype_options' value='{$ui->all_otype_options}' />";
    echo "<input type='hidden' name='rs_submission_topic' value='options' />";
    ?>

<p class="submit" style="border:none;float:right">
<input type="submit" name="rs_submit" class="button-primary" value="<?php 
    _e('Update &raquo;', 'scoper');
    ?>
" />
</p>

<?php 
    $msg = __("All settings in this form (including those on undisplayed tabs) will be reset to DEFAULTS.  Are you sure?", 'scoper');
    $js_call = "javascript:if (confirm('{$msg}')) {return true;} else {return false;}";
    ?>

<p class="submit" style="border:none;float:left">

<input type="submit" name="rs_defaults" value="<?php 
    _e('Revert to Defaults', 'scoper');
    ?>
" onclick="<?php 
    echo $js_call;
    ?>
" />
</p>
</form>
<p style='clear:both'>
</p>
</div>

<?php 
}
function scoper_admin_object_restrictions($src_name, $object_type)
{
    global $scoper, $scoper_admin;
    if (!($src = $scoper->data_sources->get($src_name)) || !empty($src->no_object_roles) || !empty($src->taxonomy_only) || $src_name == 'group') {
        wp_die(__('Invalid data source', 'scoper'));
    }
    $is_administrator = is_administrator_rs($src, 'user');
    $role_bases = array();
    if (USER_ROLES_RS && ($is_administrator || $scoper_admin->user_can_admin_object($src_name, $object_type, 0, true))) {
        $role_bases[] = ROLE_BASIS_USER;
    }
    if (GROUP_ROLES_RS && ($is_administrator || $scoper_admin->user_can_admin_object($src_name, $object_type, 0, true) || current_user_can('manage_groups'))) {
        $role_bases[] = ROLE_BASIS_GROUPS;
    }
    if (empty($role_bases)) {
        wp_die(__awp('Cheatin&#8217; uh?'));
    }
    $otype = $scoper->data_sources->member_property($src_name, 'object_types', $object_type);
    require_once dirname(__FILE__) . '/admin-bulk_rs.php';
    require_once dirname(__FILE__) . '/admin_lib-bulk-parent_rs.php';
    $role_assigner = init_role_assigner();
    $nonce_id = 'scoper-assign-roles';
    $role_codes = ScoperAdminBulk::get_role_codes();
    echo '<a name="scoper_top"></a>';
    // ==== Process Submission =====
    $err = 0;
    if (isset($_POST['rs_submit'])) {
        $err = ScoperAdminBulk::role_submission(OBJECT_SCOPE_RS, ROLE_RESTRICTION_RS, '', $src_name, $role_codes, '', $nonce_id);
        if (scoper_get_option('file_filtering')) {
            scoper_flush_file_rules();
        }
    }
    ?>


<div class="wrap agp-width97">
<?php 
    $src_otype = isset($src->object_types) ? "{$src_name}:{$object_type}" : $src_name;
    $item_label_singular = $scoper_admin->interpret_src_otype($src_otype, 'singular_name');
    $item_label = $scoper_admin->interpret_src_otype($src_otype);
    echo '<h2>' . sprintf(__('%s Restrictions', 'scoper'), $item_label_singular) . '&nbsp;&nbsp;<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">';
        $link_open = "<a href='admin.php?page=rs-{$object_type}-roles'>";
        $uses_taxonomies = scoper_get_taxonomy_usage($src_name, $object_type);
        if ($uses_taxonomies && 1 == count($uses_taxonomies)) {
            $tx_display = $scoper->taxonomies->member_property(reset($uses_taxonomies), 'display_name');
            printf(__('Reduce access to a specific %1$s by requiring some role(s) to be %2$s%3$s-assigned%4$s. Corresponding WP-assigned Roles and RS-assigned General and %5$s Role assignments are ignored.', 'scoper'), $item_label_singular, $link_open, $item_label_singular, '</a>', $tx_display);
        } elseif (count($uses_taxonomies)) {
            printf(__('Reduce access to a specific %1$s by requiring some role(s) to be %2$s%3$s-assigned%4$s. Corresponding WP-assigned Roles and RS-assigned General and Term Role assignments are ignored.', 'scoper'), $item_label_singular, $link_open, $item_label_singular, '</a>');
        } else {
            printf(__('Reduce access to a specific %1$s by requiring some role(s) to be %2$s%3$s-assigned%4$s. Corresponding WP-assigned Roles and RS-assigned General Role assignments are ignored.', 'scoper'), $item_label_singular, $link_open, $item_label_singular, '</a>');
        }
        echo '</div>';
    }
    $ignore_hierarchy = !empty($otype->ignore_object_hierarchy);
    ?>


<form action="" method="post" name="role_assign" id="role_assign">
<?php 
    wp_nonce_field($nonce_id);
    // ============ Users / Groups and Assignment Mode Selection Display ================
    if (empty($src->cols->parent) || $ignore_hierarchy) {
        $assignment_modes = array(ASSIGN_FOR_ENTITY_RS => sprintf(__('for selected %s', 'scoper'), $item_label));
    } else {
        $assignment_modes = array(ASSIGN_FOR_ENTITY_RS => sprintf(__('for selected %s', 'scoper'), $item_label), ASSIGN_FOR_CHILDREN_RS => sprintf(__('for sub-%s of selected', 'scoper'), $item_label), ASSIGN_FOR_BOTH_RS => sprintf(__('for selected and sub-%s', 'scoper'), $item_label));
    }
    $max_scopes = array('object' => __('Restrict selected roles', 'scoper'), 'blog' => __('Unrestrict selected roles', 'scoper'));
    $args = array('max_scopes' => $max_scopes, 'scope' => OBJECT_SCOPE_RS);
    ScoperAdminBulk::display_inputs(ROLE_RESTRICTION_RS, $assignment_modes, $args);
    echo '<br />';
    $args = array('default_hide_empty' => !empty($otype->admin_default_hide_empty), 'hide_roles' => true, 'scope' => OBJECT_SCOPE_RS, 'src' => $src, 'otype' => $otype);
    ScoperAdminBulk::item_tree_jslinks(ROLE_RESTRICTION_RS, $args);
    // buffer prev/next caption for display with each obj type
    //$prevtext = _ x('prev', 'abbreviated link to previous item', 'scoper');
    //$nexttext = _ x('next', 'abbreviated link to next item', 'scoper');
    $prevtext = __('prev', 'scoper');
    $nexttext = __('next', 'scoper');
    $site_url = get_option('siteurl');
    $args = array('include_child_restrictions' => true, 'return_array' => true, 'role_type' => 'rs', 'force_refresh' => true);
    $strict_objects = $scoper->get_restrictions(OBJECT_SCOPE_RS, $src_name, $args);
    $object_names = array();
    $object_status = array();
    $listed_objects = array();
    $unlisted_objects = array();
    $col_id = $src->cols->id;
    $col_parent = isset($src->cols->parent) && !$ignore_hierarchy ? $src->cols->parent : '';
    $object_ids = array();
    if (isset($strict_objects['restrictions'])) {
        foreach (array_keys($strict_objects['restrictions']) as $role_handle) {
            $object_ids = $object_ids + array_keys($strict_objects['restrictions'][$role_handle]);
        }
    } elseif (isset($strict_objects['unrestrictions'])) {
        foreach (array_keys($strict_objects['unrestrictions']) as $role_handle) {
            $object_ids = $object_ids + array_keys($strict_objects['unrestrictions'][$role_handle]);
        }
    }
    $object_ids = array_flip(array_unique($object_ids));
    // Get the obj name, parent associated with each role (also sets $object_names, $unlisted objects)
    $listed_objects = ScoperAdminBulkParent::get_objects_info($object_ids, $object_names, $object_status, $unlisted_objects, $src, $otype, $ignore_hierarchy);
    if ($col_parent) {
        if ($listed_objects) {
            if ($unlisted_objects) {
                // query for any parent objects which don't have their own role assignments
                $listed_objects = ScoperAdminBulkParent::add_missing_parents($listed_objects, $unlisted_objects, $col_parent);
            }
            // convert keys from object ID to title+ID so we can alpha sort them
            $listed_objects_alpha = array();
            foreach (array_keys($listed_objects) as $id) {
                $listed_objects_alpha[$listed_objects[$id]->{$src->cols->name} . chr(11) . $id] = $listed_objects[$id];
            }
            uksort($listed_objects_alpha, "strnatcasecmp");
            $listed_objects = ScoperAdminBulkParent::order_by_hierarchy($listed_objects_alpha, $col_id, $col_parent);
        }
        // endif any listed objects
    } else {
        // endif doing object hierarchy
        if ($listed_objects) {
            // convert keys from object ID to title+ID so we can alpha sort them
            $listed_objects_alpha = array();
            foreach (array_keys($listed_objects) as $id) {
                $listed_objects_alpha[$listed_objects[$id]->{$src->cols->name} . chr(11) . $id] = $listed_objects[$id];
            }
            uksort($listed_objects_alpha, "strnatcasecmp");
            // convert to ordinal integer index
            $listed_objects = array_combine(array_keys(array_fill(0, count($listed_objects_alpha), true)), $listed_objects_alpha);
        }
    }
    if (!$is_administrator) {
        $cu_admin_results = ScoperAdminBulk::filter_objects_listing(ROLE_RESTRICTION_RS, $strict_objects, $src, $object_type);
    } else {
        $cu_admin_results = '';
    }
    // no need to filter admins
    // membuffer ids so user_can_admin_role() doesn't trigger a separate has_cap query for each one
    if ($cu_admin_results) {
        $scoper->listed_ids[$src_name] = $cu_admin_results;
    }
    global $scoper_admin;
    $role_display = array();
    $editable_roles = array();
    $role_defs_by_otype = array();
    $role_defs_by_otype[$object_type] = $scoper->role_defs->get_matching('rs', $src_name, $object_type);
    foreach (array_keys($role_defs_by_otype[$object_type]) as $role_handle) {
        $role_display[$role_handle] = $scoper->role_defs->get_abbrev($role_handle, OBJECT_UI_RS);
        if ($cu_admin_results && !is_user_administrator_rs()) {
            foreach (array_keys($cu_admin_results) as $object_id) {
                if ($scoper_admin->user_can_admin_role($role_handle, $object_id, $src_name, $object_type)) {
                    $editable_roles[$object_id][$role_handle] = true;
                }
            }
        }
    }
    $table_captions = ScoperAdminUI::restriction_captions(OBJECT_SCOPE_RS, '', $item_label_singular, $item_label);
    $args = array('admin_items' => $cu_admin_results, 'editable_roles' => $editable_roles, 'default_hide_empty' => !empty($otype->admin_default_hide_empty), 'ul_class' => 'rs-objlist', 'object_names' => $object_names, 'object_status' => $object_status, 'table_captions' => $table_captions, 'ie_link_style' => '', 'err' => $err);
    ScoperAdminBulk::item_tree(OBJECT_SCOPE_RS, ROLE_RESTRICTION_RS, $src, $otype, $listed_objects, '', $strict_objects, $role_defs_by_otype, $role_codes, $args);
    //ScoperAdminBulk::item_tree( OBJECT_SCOPE_RS, ROLE_ASSIGNMENT_RS, $src, $otype, $all_objects, $object_roles, $strict_objects, $role_defs_by_otype, $role_codes, $args);
    echo '<hr /><div style="background-color: white;"></div>';
    echo '<div class="rs-objlistkey">';
    $args = array('display_links' => true, 'display_restriction_key' => true);
    ScoperAdminUI::role_owners_key($otype, $args);
    echo '</div>';
    echo '</form><br /><h4 style="margin-bottom:0.1em"><a name="scoper_notes"></a>' . __("Notes", 'scoper') . ':</h4><ul class="rs-notes">';
    echo '<li>';
    printf(__('To edit all roles for any %1$s, click on the %1$s name.', 'scoper'), $otype->labels->singular_name);
    echo '</li>';
    echo '<li>';
    printf(__("To edit the %s via its default editor, click on the ID link.", 'scoper'), $otype->labels->singular_name);
    echo '</li>';
    if (!$is_administrator) {
        echo '<li>';
        printf(__('To enhance performance, the role editing checkboxes here may not include some roles which you can only edit due to your own %1$s-specific role. In such cases, click on the editing link to edit roles for the individual %1$s.', 'scoper'), $otype->labels->singular_name);
        echo '</li>';
    }
    echo '</ul>';
    echo '<a href="#scoper_top">' . __('top', 'scoper') . '</a>';
    ?>

</div>
<?php 
}
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&#8217; 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 '&nbsp;&nbsp;<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 scoper_admin_section_roles($taxonomy)
{
    global $scoper, $scoper_admin, $wpdb;
    if (!($tx = $scoper->taxonomies->get($taxonomy))) {
        wp_die(__('Invalid taxonomy', 'scoper'));
    }
    $is_administrator = is_administrator_rs($tx, 'user');
    $role_bases = array();
    if (USER_ROLES_RS && ($is_administrator || $scoper_admin->user_can_admin_terms($taxonomy))) {
        $role_bases[] = ROLE_BASIS_USER;
    }
    if (GROUP_ROLES_RS && ($is_administrator || $scoper_admin->user_can_admin_terms($taxonomy) || current_user_can('manage_groups'))) {
        $role_bases[] = ROLE_BASIS_GROUPS;
    }
    if (empty($role_bases)) {
        wp_die(__awp('Cheatin&#8217; uh?'));
    }
    require_once dirname(__FILE__) . '/admin-bulk_rs.php';
    require_once dirname(__FILE__) . '/role_assignment_lib_rs.php';
    $role_assigner = init_role_assigner();
    $nonce_id = 'scoper-assign-roles';
    $agents = ScoperAdminBulk::get_agents($role_bases);
    $agent_names = ScoperAdminBulk::agent_names($agents);
    $agent_list_prefix = ScoperAdminBulk::agent_list_prefixes();
    $agent_caption_plural = ScoperAdminBulk::agent_captions_plural($role_bases);
    $role_bases = array_keys($agents);
    $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_ASSIGNMENT_RS, $role_bases, $taxonomy, $role_codes, $agent_caption_plural, $nonce_id);
    } else {
        $err = 0;
    }
    // =========================== Prepare Data ===============================
    //$term_roles [role_basis] [src_name] [object_id] [role_handle] [agent_id] = array( 'assign_for' => ENUM , 'inherited_from' => assignment_id)
    $term_roles = array();
    foreach ($role_bases as $role_basis) {
        $term_roles[$role_basis] = ScoperRoleAssignments::get_assigned_roles(TERM_SCOPE_RS, $role_basis, $taxonomy);
    }
    $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" id="rs_admin_wrap">
<?php 
    $tx->labels->singular_name = $tx->labels->singular_name;
    echo '<h2>' . sprintf(__('%s Roles', 'scoper'), $tx->labels->singular_name) . '&nbsp;&nbsp;<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 (!empty($tx->requires_term)) {
            //printf(_ x('Grant capabilities within a specific %2$s, potentially more than a user\'s WP role would allow. To reduce access, define %1$s%2$s&nbsp;Restrictions%3$s.', 'arguments are link open, taxonomy name, link close', 'scoper'), "<a href='admin.php?page=rs-$taxonomy-restrictions_t'>", $tx->labels->singular_name, '</a>');
            printf(__('Grant capabilities within a specific %2$s, potentially more than a user\'s WP role would allow. To reduce access, define %1$s%2$s&nbsp;Restrictions%3$s.', 'scoper'), "<a href='admin.php?page=rs-{$taxonomy}-restrictions_t'>", $tx->labels->singular_name, '</a>');
        } else {
            printf(__('Grant capabilities within a specific %s, potentially more than a user\'s WP role would allow.', 'scoper'), $tx->labels->singular_name);
        }
        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->singular_name);
        echo '</div>';
        return;
    }
    ?>

<form action="" method="post" name="role_assign" 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 />';
    // ============ Users / Groups and Assignment Mode Selection Display ================
    $tx_label = agp_strtolower($tx->labels->name);
    $parent_col = !empty($tx_src->cols->parent) ? $tx_src->cols->parent : '';
    if (!$parent_col || !empty($tx->uses_standard_schema) && empty($tx->hierarchical)) {
        $assignment_modes = array(ASSIGN_FOR_ENTITY_RS => __('Assign', 'scoper'), REMOVE_ASSIGNMENT_RS => __('Remove', 'scoper'));
    } else {
        $assignment_modes = array(ASSIGN_FOR_ENTITY_RS => sprintf(__('Assign for selected %s', 'scoper'), $tx_label), ASSIGN_FOR_CHILDREN_RS => sprintf(__('Assign for sub-%s of selected', 'scoper'), $tx_label), ASSIGN_FOR_BOTH_RS => sprintf(__('Assign for selected and sub-%s', 'scoper'), $tx_label), REMOVE_ASSIGNMENT_RS => __('Remove', 'scoper'));
    }
    $args = array('role_bases' => $role_bases, 'agents' => $agents, 'agent_caption_plural' => $agent_caption_plural, 'scope' => TERM_SCOPE_RS, 'src_or_tx_name' => $taxonomy);
    ScoperAdminBulk::display_inputs(ROLE_ASSIGNMENT_RS, $assignment_modes, $args);
    $args = array('role_bases' => $role_bases);
    ScoperAdminBulk::item_tree_jslinks(ROLE_ASSIGNMENT_RS, $args);
    echo '<div id="rs-section-roles">';
    // 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);
    $src_name = $tx->object_source;
    $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, '', compact('src_name', 'object_type'))) {
                    $editable_roles[$id][$role_handle] = true;
                }
            }
        }
    }
    $args = array('admin_items' => $admin_terms, 'editable_roles' => $editable_roles, 'role_bases' => $role_bases, 'agent_names' => $agent_names, 'agent_caption_plural' => $agent_caption_plural, 'agent_list_prefix' => $agent_list_prefix, 'ul_class' => 'rs-termlist', 'ie_link_style' => $ie_link_style, 'err' => $err);
    ScoperAdminBulk::item_tree(TERM_SCOPE_RS, ROLE_ASSIGNMENT_RS, $tx_src, $tx, $all_terms, $term_roles, $strict_terms, $role_defs_by_otype, $role_codes, $args);
    echo '<hr /><div style="background-color: white;"></div>';
    echo '</div>';
    //rs-section-roles
    //================================ Notes Section ==================================
    ?>

</form>
<a name="scoper_notes"></a>
<?php 
    if ('nav_menu' != $taxonomy) {
        // TODO: better logic for note construction when related custom type is not being RS-filtered
        $args = array('display_links' => true, 'display_restriction_key' => true);
        ScoperAdminUI::role_owners_key($tx, $args);
        $osrc = $scoper->data_sources->get($tx->object_source);
        echo '<br /><h4 style="margin-bottom:0.1em">' . __("Notes", 'scoper') . ':</h4><ul class="rs-notes">';
        echo '<li>';
        _e('A Role is a collection of capabilities.', 'scoper');
        echo '</li>';
        echo '<li>';
        _e("Capabilities in a user's WordPress Role (and, optionally, RS-assigned General Roles) enable site-wide operations (read/edit/delete) on some object type (post/page/link), perhaps of a certain status (private/published/draft).", 'scoper');
        echo '</li>';
        echo '<li>';
        if (empty($osrc->no_object_roles)) {
            printf(__('Scoped Roles can grant users these same WordPress capabilities on a per-%1$s or per-%2$s basis. Useful in fencing off sections your site.', 'scoper'), $tx->labels->singular_name, $osrc->labels->singular_name);
        } else {
            printf(__('Scoped Roles can grant users these same WordPress capabilities on a per-%1$s basis. Useful in fencing off sections your site.', 'scoper'), $tx->labels->singular_name, $osrc->labels->singular_name);
        }
        echo '</li>';
        echo '<li>';
        printf(__('Users with a %1$s Role assignment may have capabilities beyond their General Role(s) for %2$s in the specified %1$s.', 'scoper'), $tx->labels->singular_name, $osrc->labels->name);
        echo '</li>';
        if (!empty($tx->requires_term)) {
            echo '<li>';
            printf(__('If a role is restricted for some %s, general (site-wide) assignments of that role are ignored.', 'scoper'), $tx->labels->singular_name);
            echo '</li>';
            echo '<li>';
            printf(__('If a %1$s is in multiple %2$s, permission is granted if any %3$s has a qualifying role assignment or permits a qualifying General Role.', 'scoper'), $osrc->labels->singular_name, $tx->labels->name, $tx->labels->singular_name);
            echo '</li>';
        }
        if (empty($osrc->no_object_roles)) {
            echo '<li>';
            printf(__('If a role is restricted for some requested %1$s, %2$s-assignment and General-assignment of that role are ignored.', 'scoper'), $osrc->labels->singular_name, $tx->labels->singular_name);
            echo '</li>';
        }
        echo '<li>';
        _e('Administrators are exempted from Role Restrictions.', 'scoper');
        echo '</li></ul>';
    }
    //endif showing notes
    echo '<a href="#scoper_top">' . __('top', 'scoper') . '</a>';
    ?>

</div>
<?php 
}