/**
 * Handle add capability form submission.
 * @return int new capability's id or false if unsuccessful
 */
function groups_admin_capabilities_add_submit()
{
    global $wpdb;
    if (!current_user_can(GROUPS_ADMINISTER_GROUPS)) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    if (!wp_verify_nonce($_POST[GROUPS_ADMIN_GROUPS_NONCE], 'capabilities-add')) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    $capability = isset($_POST['capability-field']) ? $_POST['capability-field'] : null;
    $description = isset($_POST['description-field']) ? $_POST['description-field'] : '';
    return Groups_Capability::create(compact("capability", "description"));
}
/**
 * Handle remove form submission.
 */
function groups_admin_capabilities_remove_submit()
{
    global $wpdb;
    $result = false;
    if (!current_user_can(GROUPS_ADMINISTER_GROUPS)) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    if (!wp_verify_nonce($_POST[GROUPS_ADMIN_GROUPS_NONCE], 'capabilities-remove')) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    $capability_id = isset($_POST['capability-id-field']) ? $_POST['capability-id-field'] : null;
    $capability = Groups_Capability::read($capability_id);
    if ($capability) {
        if ($capability->capability !== Groups_Post_Access::READ_POST_CAPABILITY) {
            $result = Groups_Capability::delete($capability_id);
        }
    }
    return $result;
}
/**
 * Handle edit form submission.
 */
function groups_admin_capabilities_edit_submit()
{
    $result = false;
    if (!current_user_can(GROUPS_ADMINISTER_GROUPS)) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    if (!wp_verify_nonce($_POST[GROUPS_ADMIN_GROUPS_NONCE], 'capabilities-edit')) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    $capability_id = isset($_POST['capability-id-field']) ? $_POST['capability-id-field'] : null;
    $capability = Groups_Capability::read($capability_id);
    if ($capability) {
        $capability_id = $capability->capability_id;
        if ($capability->capability !== Groups_Post_Access::READ_POST_CAPABILITY) {
            $capability_field = isset($_POST['capability-field']) ? $_POST['capability-field'] : null;
        } else {
            $capability_field = Groups_Post_Access::READ_POST_CAPABILITY;
        }
        if (!empty($capability_field)) {
            $update = true;
            if ($other_capability = Groups_Capability::read_by_capability($capability_field)) {
                if ($other_capability->capability_id != $capability_id) {
                    Groups_Admin::add_message(sprintf(__('The <em>%s</em> capability already exists and cannot be assigned to this one.', GROUPS_PLUGIN_DOMAIN), stripslashes(wp_filter_nohtml_kses($other_capability->capability))), 'error');
                    $update = false;
                }
            }
            if ($update) {
                $description = isset($_POST['description-field']) ? $_POST['description-field'] : '';
                $capability_id = Groups_Capability::update(array('capability_id' => $capability_id, 'capability' => $capability_field, 'description' => $description));
                if ($capability_id) {
                    $result = $capability_id;
                } else {
                    Groups_Admin::add_message(sprintf(__('The <em>%s</em> capability could not be updated.', GROUPS_PLUGIN_DOMAIN), stripslashes(wp_filter_nohtml_kses($capability))), 'error');
                }
            }
        } else {
            Groups_Admin::add_message(__('The <em>Capability</em> must not be empty.', GROUPS_PLUGIN_DOMAIN), 'error');
        }
    }
    return $result;
}
/**
 * Handle edit form submission.
 */
function groups_admin_capabilities_edit_submit()
{
    if (!current_user_can(GROUPS_ADMINISTER_GROUPS)) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    if (!wp_verify_nonce($_POST[GROUPS_ADMIN_GROUPS_NONCE], 'capabilities-edit')) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    $capability_id = isset($_POST['capability-id-field']) ? $_POST['capability-id-field'] : null;
    $capability = Groups_Capability::read($capability_id);
    if ($capability) {
        $capability_id = $capability->capability_id;
        if ($capability->capability !== Groups_Post_Access::READ_POST_CAPABILITY) {
            $capability = isset($_POST['capability-field']) ? $_POST['capability-field'] : null;
        } else {
            $capability = Groups_Post_Access::READ_POST_CAPABILITY;
        }
        $description = isset($_POST['description-field']) ? $_POST['description-field'] : '';
        return Groups_Capability::update(compact("capability_id", "capability", "description"));
    } else {
        return false;
    }
}
/**
 * Handle add capability form submission.
 * @return int new capability's id or false if unsuccessful
 */
function groups_admin_capabilities_add_submit()
{
    global $wpdb;
    if (!current_user_can(GROUPS_ADMINISTER_GROUPS)) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    if (!wp_verify_nonce($_POST[GROUPS_ADMIN_GROUPS_NONCE], 'capabilities-add')) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    $capability = isset($_POST['capability-field']) ? $_POST['capability-field'] : null;
    $description = isset($_POST['description-field']) ? $_POST['description-field'] : '';
    $capability_id = Groups_Capability::create(compact("capability", "description"));
    if (!$capability_id) {
        if (empty($capability)) {
            Groups_Admin::add_message(__('The <em>Capability</em> must not be empty.', GROUPS_PLUGIN_DOMAIN), 'error');
        } else {
            if (Groups_Capability::read_by_capability($capability)) {
                Groups_Admin::add_message(sprintf(__('The <em>%s</em> capability already exists.', GROUPS_PLUGIN_DOMAIN), stripslashes(wp_filter_nohtml_kses($capability))), 'error');
            }
        }
    }
    return $capability_id;
}
 /**
  * Adds an access capability requirement.
  * 
  * $map must contain 'post_id' (*)
  * 
  * For now this only should be used to add the READ_POST_CAPABILITY which
  * it does automatically. Nothing else is checked for granting access.
  * 
  * (*) Revisions : As of Groups 1.3.13 and at WordPress 3.6.1, as
  * add_post_meta stores postmeta for the revision's parent, we retrieve
  * the parent's post ID if it applies and check against that to see if
  * that capability is already present. This is to avoid duplicating
  * the already existing postmeta entry (which ocurred in previous
  * versions).
  * 
  * @param array $map
  * @return true if the capability could be added to the post, otherwis false
  */
 public static function create($map)
 {
     extract($map);
     $result = false;
     if (!isset($capability)) {
         $capability = self::READ_POST_CAPABILITY;
     }
     if (!empty($post_id) && !empty($capability)) {
         if (Groups_Capability::read_by_capability($capability)) {
             if ($revision_parent_id = wp_is_post_revision($post_id)) {
                 $post_id = $revision_parent_id;
             }
             if (!in_array($capability, get_post_meta($post_id, self::POSTMETA_PREFIX . self::READ_POST_CAPABILITY))) {
                 $result = add_post_meta($post_id, self::POSTMETA_PREFIX . self::READ_POST_CAPABILITY, $capability);
             }
         }
     }
     return $result;
 }
 /**
  * Update user-capability relation.
  * 
  * This changes nothing so as of now it's pointless to even call this.
  * 
  * @param array $map
  * @return true if successful, false otherwise
  */
 public static function update($map)
 {
     $result = false;
     //		if ( !empty( $user_id ) && !empty( $capability_id) ) {
     if (!empty($capability_id)) {
         // make sure user and capability exist
         if (false !== Groups_Utility::id($user_id) && get_user_by("id", $user_id) && Groups_Capability::read($capability_id)) {
             $result = true;
             do_action("groups_updated_user_capability", $user_id, $capability_id);
         }
     }
     return $result;
 }
 /**
  * Update group-capability relation.
  * 
  * This changes nothing so as of now it's pointless to even call this.
  * 
  * @param array $map
  * @return true if successful, false otherwise
  */
 public static function update($map)
 {
     $result = false;
     if (!empty($group_id) && !empty($capability_id)) {
         // make sure group and capability exist
         if (Groups_Group::read($group_id) && Groups_Capability::read($capability_id)) {
             $result = true;
             do_action("groups_updated_group_capability", $group_id, $capability_id);
         }
     }
     return $result;
 }
Example #9
0
/**
 * Options admin screen.
 */
function groups_admin_options()
{
    global $wpdb, $wp_roles;
    if (!current_user_can(GROUPS_ADMINISTER_OPTIONS)) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    $is_sitewide_plugin = false;
    if (is_multisite()) {
        $active_sitewide_plugins = get_site_option('active_sitewide_plugins', array());
        $active_sitewide_plugins = array_keys($active_sitewide_plugins);
        $is_sitewide_plugin = in_array('groups/groups.php', $active_sitewide_plugins);
    }
    echo '<div class="groups-options">';
    echo '<div>' . '<h2>' . __('Groups options', GROUPS_PLUGIN_DOMAIN) . '</h2>' . '</div>';
    $caps = array(GROUPS_ACCESS_GROUPS => __('Access Groups', GROUPS_PLUGIN_DOMAIN), GROUPS_ADMINISTER_GROUPS => __('Administer Groups', GROUPS_PLUGIN_DOMAIN), GROUPS_ADMINISTER_OPTIONS => __('Administer Groups plugin options', GROUPS_PLUGIN_DOMAIN));
    //
    // handle options form submission
    //
    if (isset($_POST['submit'])) {
        if (wp_verify_nonce($_POST[GROUPS_ADMIN_OPTIONS_NONCE], 'admin')) {
            // admin override
            if (empty($_POST[GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE])) {
                $admin_override = false;
            } else {
                $admin_override = true;
            }
            // Don't move this to the plugin options, access will be faster
            add_option(GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE, $admin_override);
            // WP 3.3.1 : update alone wouldn't create the option when value is false
            update_option(GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE, $admin_override);
            $post_types_option = Groups_Options::get_option(Groups_Post_Access::POST_TYPES, array());
            $post_types = get_post_types(array('public' => true));
            foreach ($post_types as $post_type) {
                $post_types_option[$post_type]['add_meta_box'] = in_array($post_type, $_POST['add_meta_boxes']);
            }
            Groups_Options::update_option(Groups_Post_Access::POST_TYPES, $post_types_option);
            $valid_read_caps = array(Groups_Post_Access::READ_POST_CAPABILITY);
            if (!empty($_POST[GROUPS_READ_POST_CAPABILITIES])) {
                $read_caps = $_POST[GROUPS_READ_POST_CAPABILITIES];
                foreach ($read_caps as $read_cap) {
                    if (!in_array($read_cap, $valid_read_caps) && ($valid_cap = Groups_Capability::read($read_cap))) {
                        $valid_read_caps[] = $valid_cap->capability;
                    }
                }
            }
            Groups_Options::update_option(Groups_Post_Access::READ_POST_CAPABILITIES, $valid_read_caps);
            // tree view
            if (!empty($_POST[GROUPS_SHOW_TREE_VIEW])) {
                Groups_Options::update_option(GROUPS_SHOW_TREE_VIEW, true);
            } else {
                Groups_Options::update_option(GROUPS_SHOW_TREE_VIEW, false);
            }
            // show in user profiles
            Groups_Options::update_option(GROUPS_SHOW_IN_USER_PROFILE, !empty($_POST[GROUPS_SHOW_IN_USER_PROFILE]));
            // roles & capabilities
            $rolenames = $wp_roles->get_names();
            foreach ($rolenames as $rolekey => $rolename) {
                $role = $wp_roles->get_role($rolekey);
                foreach ($caps as $capkey => $capname) {
                    $role_cap_id = $rolekey . '-' . $capkey;
                    if (!empty($_POST[$role_cap_id])) {
                        $role->add_cap($capkey);
                    } else {
                        $role->remove_cap($capkey);
                    }
                }
            }
            Groups_Controller::assure_capabilities();
            if (!$is_sitewide_plugin) {
                // delete data
                if (!empty($_POST['delete-data'])) {
                    Groups_Options::update_option('groups_delete_data', true);
                } else {
                    Groups_Options::update_option('groups_delete_data', false);
                }
            }
        }
    }
    $admin_override = get_option(GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE, GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE_DEFAULT);
    $show_tree_view = Groups_Options::get_option(GROUPS_SHOW_TREE_VIEW, GROUPS_SHOW_TREE_VIEW_DEFAULT);
    $show_in_user_profile = Groups_Options::get_option(GROUPS_SHOW_IN_USER_PROFILE, GROUPS_SHOW_IN_USER_PROFILE_DEFAULT);
    $rolenames = $wp_roles->get_names();
    $caps_table = '<table class="groups-permissions">';
    $caps_table .= '<thead>';
    $caps_table .= '<tr>';
    $caps_table .= '<td class="role">';
    $caps_table .= __('Role', GROUPS_PLUGIN_DOMAIN);
    $caps_table .= '</td>';
    foreach ($caps as $cap) {
        $caps_table .= '<td class="cap">';
        $caps_table .= $cap;
        $caps_table .= '</td>';
    }
    $caps_table .= '</tr>';
    $caps_table .= '</thead>';
    $caps_table .= '<tbody>';
    foreach ($rolenames as $rolekey => $rolename) {
        $role = $wp_roles->get_role($rolekey);
        $caps_table .= '<tr>';
        $caps_table .= '<td>';
        $caps_table .= translate_user_role($rolename);
        $caps_table .= '</td>';
        foreach ($caps as $capkey => $capname) {
            if ($role->has_cap($capkey)) {
                $checked = ' checked="checked" ';
            } else {
                $checked = '';
            }
            $caps_table .= '<td class="checkbox">';
            $role_cap_id = $rolekey . '-' . $capkey;
            $caps_table .= '<input type="checkbox" name="' . $role_cap_id . '" id="' . $role_cap_id . '" ' . $checked . '/>';
            $caps_table .= '</td>';
        }
        $caps_table .= '</tr>';
    }
    $caps_table .= '</tbody>';
    $caps_table .= '</table>';
    $delete_data = Groups_Options::get_option('groups_delete_data', false);
    //
    // print the options form
    //
    echo '<form action="" name="options" method="post">' . '<p>' . '<input class="button" type="submit" name="submit" value="' . __('Save', GROUPS_PLUGIN_DOMAIN) . '"/>' . '</p>' . '<div>' . '<h3>' . __('Administrator Access Override', GROUPS_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<label>' . '<input name="' . GROUPS_ADMINISTRATOR_ACCESS_OVERRIDE . '" type="checkbox" ' . ($admin_override ? 'checked="checked"' : '') . '/>' . __('Administrators override all access permissions derived from Groups capabilities.', GROUPS_PLUGIN_DOMAIN) . '</label>' . '</p>';
    echo '<h3>' . __('Access restricions', GROUPS_PLUGIN_DOMAIN) . '</h3>';
    echo '<h4>' . __('Post types', GROUPS_PLUGIN_DOMAIN) . '</h4>';
    echo '<p class="description">' . __('Show access restrictions for these post types.', GROUPS_PLUGIN_DOMAIN) . '</p>';
    $post_types_option = Groups_Options::get_option(Groups_Post_Access::POST_TYPES, array());
    $post_types = get_post_types(array('public' => true));
    echo '<ul>';
    foreach ($post_types as $post_type) {
        $post_type_object = get_post_type_object($post_type);
        echo '<li>';
        echo '<label>';
        $label = $post_type;
        $labels = isset($post_type_object->labels) ? $post_type_object->labels : null;
        if ($labels !== null && isset($labels->singular_name)) {
            $label = __($labels->singular_name);
        }
        $checked = !isset($post_types_option[$post_type]['add_meta_box']) || $post_types_option[$post_type]['add_meta_box'] ? ' checked="checked" ' : '';
        echo '<input name="add_meta_boxes[]" type="checkbox" value="' . esc_attr($post_type) . '" ' . $checked . '/>';
        echo $label;
        echo '</label>';
        echo '</li>';
    }
    echo '<ul>';
    echo '<p class="description">' . __('This determines for which post types access restriction settings are offered.', GROUPS_PLUGIN_DOMAIN) . '<br/>' . __('Disabling this setting for a post type does not remove existing access restrictions on individual posts of that type.', GROUPS_PLUGIN_DOMAIN) . '<br/>' . '</p>';
    echo '<h4>' . __('Capabilities', GROUPS_PLUGIN_DOMAIN) . '</h4>';
    echo '<p class="description">' . __('Include these capabilities to enforce read access on posts. The selected capabilities will be offered to restrict access to posts.', GROUPS_PLUGIN_DOMAIN) . '</p>';
    $capability_table = _groups_get_tablename("capability");
    $capabilities = $wpdb->get_results("SELECT * FROM {$capability_table} ORDER BY capability");
    $applicable_read_caps = Groups_Options::get_option(Groups_Post_Access::READ_POST_CAPABILITIES, array(Groups_Post_Access::READ_POST_CAPABILITY));
    foreach ($capabilities as $capability) {
        $checked = in_array($capability->capability, $applicable_read_caps) ? ' checked="checked" ' : '';
        if ($capability->capability == Groups_Post_Access::READ_POST_CAPABILITY) {
            $checked .= ' readonly="readonly" disabled="disabled" ';
        }
        echo '<label>';
        echo '<input name="' . GROUPS_READ_POST_CAPABILITIES . '[]" ' . $checked . ' type="checkbox" value="' . esc_attr($capability->capability_id) . '" />';
        echo wp_filter_nohtml_kses($capability->capability);
        echo '</label>';
        echo ' ';
        echo '<span class="description">' . wp_filter_nohtml_kses($capability->description) . '</span>';
        echo '<br/>';
    }
    echo '<h3>' . __('User profiles', GROUPS_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<label>' . '<input name="' . GROUPS_SHOW_IN_USER_PROFILE . '" type="checkbox" ' . ($show_in_user_profile ? 'checked="checked"' : '') . '/>' . __('Show groups in user profiles.', GROUPS_PLUGIN_DOMAIN) . '</label>' . '</p>';
    echo '<h3>' . __('Tree view', GROUPS_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<label>' . '<input name="' . GROUPS_SHOW_TREE_VIEW . '" type="checkbox" ' . ($show_tree_view ? 'checked="checked"' : '') . '/>' . __('Show the Groups tree view.', GROUPS_PLUGIN_DOMAIN) . '</label>' . '</p>';
    echo '<h3>' . __('Permissions', GROUPS_PLUGIN_DOMAIN) . '</h3>' . '<p>' . __('These permissions apply to Groups management. They do not apply to access permissions derived from Groups capabilities.', GROUPS_PLUGIN_DOMAIN) . '</p>' . $caps_table . '<p class="description">' . __('A minimum set of permissions will be preserved.', GROUPS_PLUGIN_DOMAIN) . '<br/>' . __('If you lock yourself out, please ask an administrator to help.', GROUPS_PLUGIN_DOMAIN) . '</p>';
    if (!$is_sitewide_plugin) {
        echo '<h3>' . __('Deactivation and data persistence', GROUPS_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<label>' . '<input name="delete-data" type="checkbox" ' . ($delete_data ? 'checked="checked"' : '') . '/>' . __('Delete all Groups plugin data on deactivation', GROUPS_PLUGIN_DOMAIN) . '</label>' . '</p>' . '<p class="description warning">' . __('CAUTION: If this option is active while the plugin is deactivated, ALL plugin settings and data will be DELETED. If you are going to use this option, now would be a good time to make a backup. By enabling this option you agree to be solely responsible for any loss of data or any other consequences thereof.', GROUPS_PLUGIN_DOMAIN) . '</p>';
    }
    echo '<p>' . wp_nonce_field('admin', GROUPS_ADMIN_OPTIONS_NONCE, true, false) . '<input class="button" type="submit" name="submit" value="' . __('Save', GROUPS_PLUGIN_DOMAIN) . '"/>' . '</p>' . '</div>' . '</form>';
    echo '</div>';
    // .groups-options
    Groups_Help::footer();
}
 /**
  * Remove capability and its relations.
  * 
  * @param int $capability_id
  * @return capability_id if successful, false otherwise
  */
 public static function delete($capability_id)
 {
     global $wpdb;
     $result = false;
     // avoid nonsense requests
     if ($capability = Groups_Capability::read($capability_id)) {
         $capability_table = _groups_get_tablename('capability');
         // get rid of it
         if ($rows = $wpdb->query($wpdb->prepare("DELETE FROM {$capability_table} WHERE capability_id = %d", Groups_Utility::id($capability_id)))) {
             $result = $capability_id;
             if (!empty($capability->capability)) {
                 wp_cache_delete(self::READ_BY_CAPABILITY . '_' . $capability->capability, self::CACHE_GROUP);
                 do_action('groups_deleted_capability_capability', $capability->capability);
             }
             do_action("groups_deleted_capability", $result);
         }
     }
     return $result;
 }
 /**
  * Save capabilities for attachment post type (Media).
  * When multiple attachments are saved, this is called once for each.
  * @param array $post post data
  * @param array $attachment attachment field data
  * @return array
  */
 public static function attachment_fields_to_save($post, $attachment)
 {
     $post_types_option = Groups_Options::get_option(Groups_Post_Access::POST_TYPES, array());
     if (!isset($post_types_option['attachment']['add_meta_box']) || $post_types_option['attachment']['add_meta_box']) {
         if (current_user_can('edit_attachment')) {
             Groups_Post_Access::delete($post['ID'], null);
             if (!empty($attachment[self::CAPABILITY])) {
                 foreach ($attachment[self::CAPABILITY] as $capability_id) {
                     if ($capability = Groups_Capability::read($capability_id)) {
                         Groups_Post_Access::create(array('post_id' => $post['ID'], 'capability' => $capability->capability));
                     }
                 }
             }
         }
     }
     return $post;
 }
Example #12
0
 function groups_tests()
 {
     assert_options(ASSERT_ACTIVE, true);
     assert_options(ASSERT_WARNING, true);
     assert_options(ASSERT_BAIL, false);
     //
     // PART 1 : create test data
     //
     // *** groups ***
     // create valid test groups
     //
     //		  Fruits [dance] {foo}
     //		/	   \
     //   Sweet {dol}   Sour [sing]
     //	 |			|
     //   Banana {baz}  Lemon {bar}
     //
     // All groups can dance.
     // Only Sour and Lemon can sing.
     $fruits_group_id = Groups_Group::create(array('name' => 'Fruits'));
     assert('$fruits_group_id !== false');
     $sweet_group_id = Groups_Group::create(array('name' => 'Sweet', 'parent_id' => $fruits_group_id));
     assert('$sweet_group_id !== false');
     $sour_group_id = Groups_Group::create(array('name' => 'Sour', 'parent_id' => $fruits_group_id));
     assert('$sour_group_id !== false');
     $lemon_group_id = Groups_Group::create(array('name' => 'Lemon', 'parent_id' => $sour_group_id));
     assert('$lemon_group_id !== false');
     $banana_group_id = Groups_Group::create(array('name' => 'Banana', 'parent_id' => $sweet_group_id));
     assert('$banana_group_id !== false');
     // fail to create group with missing name
     $bogus_group_id = Groups_Group::create(array());
     assert('$bogus_group_id === false; /* empty name */');
     // fail to create group with wrong parent_id
     $bogus_group_id = Groups_Group::create(array('name' => 'bogus', 'parent_id' => -1));
     assert('$bogus_group_id === false; /* wrong parent_id */');
     // *** capabilities ***
     $sing_capability_id = Groups_Capability::create(array('capability' => 'sing'));
     assert('$sing_capability_id !== false');
     $dance_capability_id = Groups_Capability::create(array('capability' => 'dance'));
     assert('$dance_capability_id !== false');
     $clap_capability_id = Groups_Capability::create(array('capability' => 'clap'));
     assert('$clap_capability_id !== false');
     // read capability by id
     assert('Groups_Capability::read( $sing_capability_id )');
     // read capability by unique label
     assert('Groups_Capability::read_by_capability( "dance" )');
     // *** users ***
     // create test users
     $fooname = 'foo' . rand(0, 100);
     $foo_user_id = wp_create_user($fooname, 'foo', $fooname . '@example.com');
     assert('$foo_user_id instanceof WP_Error === false');
     $barname = 'bar' . rand(0, 100);
     $bar_user_id = wp_create_user($barname, 'bar', $barname . '@example.com');
     assert('$bar_user_id instanceof WP_Error === false');
     // this user is used to test the automatic resolution of its relationship
     // with the banana group when the group is deleted
     // it's also used to test automatic resolution of its "clap" capability
     // after that capability has been deleted
     $bazname = 'baz' . rand(0, 100);
     $baz_user_id = wp_create_user($bazname, 'baz', $bazname . '@example.com');
     assert('$baz_user_id instanceof WP_Error === false');
     // this user is deleted, the group relation must be deleted automatically
     $dolname = 'dol' . rand(0, 100);
     $dol_user_id = wp_create_user($dolname, 'dol', $dolname . ' @example.com');
     assert('$dol_user_id instanceof WP_Error === false');
     // this user is a simple editor, used to test WordPress capabilities
     $editorname = 'rotide' . rand(0, 100);
     $editor_user_id = wp_create_user($editorname, 'rotide', $editorname . '@example.com');
     assert('$editor_user_id instanceof WP_Error === false');
     if (!$editor_user_id instanceof WP_Error) {
         $editor_user = new WP_User($editor_user_id);
         $editor_user->set_role('editor');
     } else {
         $editor_user_id = false;
     }
     // *** users & groups ***
     // add valid users to groups
     //		 echo "foo user id: $foo_user_id group: $fruits_group_id<br/>";
     assert('Groups_User_Group::create(array( "user_id" => $foo_user_id, "group_id" => $fruits_group_id ) )');
     assert('Groups_User_Group::create(array( "user_id" => $bar_user_id, "group_id" => $lemon_group_id ) )');
     assert('Groups_User_Group::create(array( "user_id" => $baz_user_id, "group_id" => $banana_group_id ) )');
     assert('Groups_User_Group::create(array( "user_id" => $dol_user_id, "group_id" => $sweet_group_id ) )');
     // add invalid user to group
     assert('Groups_User_Group::create(array( "user_id" => -1, "group_id" => $sweet_group_id ) ) === false');
     // add valid user to invalid group
     assert('Groups_User_Group::create(array( "user_id" => $dol_user_id, "group_id" => -1 ) ) === false');
     // define capabilities for groups
     assert('Groups_Group_Capability::create( array( "group_id" => $fruits_group_id, "capability_id" => $dance_capability_id ) )');
     assert('Groups_Group_Capability::create( array( "group_id" => $sour_group_id, "capability_id" => $sing_capability_id ) )');
     // define capabilities for users
     assert('Groups_User_Capability::create( array( "user_id" => $foo_user_id, "capability_id" => $clap_capability_id ) )');
     assert('Groups_User_Capability::create( array( "user_id" => $baz_user_id, "capability_id" => $clap_capability_id ) )');
     // check groups that can dance (all)
     // just reading will not check the hierarchy of course ...
     assert('Groups_Group_Capability::read( $fruits_group_id, $dance_capability_id )');
     assert('Groups_Group_Capability::read( $sweet_group_id, $dance_capability_id ) === false');
     assert('Groups_Group_Capability::read( $banana_group_id, $dance_capability_id ) === false');
     assert('Groups_Group_Capability::read( $sour_group_id, $dance_capability_id ) === false');
     assert('Groups_Group_Capability::read( $lemon_group_id, $dance_capability_id ) === false');
     // same for check on groups that can sing
     assert('Groups_Group_Capability::read( $fruits_group_id, $sing_capability_id ) === false');
     assert('Groups_Group_Capability::read( $sweet_group_id, $sing_capability_id ) === false');
     assert('Groups_Group_Capability::read( $banana_group_id, $sing_capability_id ) === false');
     assert('Groups_Group_Capability::read( $sour_group_id, $sing_capability_id )');
     assert('Groups_Group_Capability::read( $lemon_group_id, $sing_capability_id ) === false');
     // hierarchical groups
     $fruits_group = new Groups_Group($fruits_group_id);
     $sweet_group = new Groups_Group($sweet_group_id);
     $banana_group = new Groups_Group($banana_group_id);
     $sour_group = new Groups_Group($sour_group_id);
     $lemon_group = new Groups_Group($lemon_group_id);
     // retrieve users
     assert('count( $fruits_group->users ) > 0');
     // all should be able to "dance" : check by capability label ...
     assert('$fruits_group->can( "dance" )');
     assert('$sweet_group->can( "dance" )');
     assert('$banana_group->can( "dance" )');
     assert('$sour_group->can( "dance" )');
     assert('$lemon_group->can( "dance" )');
     // ... or id
     assert('$fruits_group->can( $dance_capability_id )');
     assert('$sweet_group->can( $dance_capability_id )');
     assert('$banana_group->can( $dance_capability_id )');
     assert('$sour_group->can( $dance_capability_id )');
     assert('$lemon_group->can( $dance_capability_id )');
     // only sour and lemon can sing:
     assert('!$fruits_group->can( "sing" )');
     assert('!$sweet_group->can( "sing" )');
     assert('!$banana_group->can( "sing" )');
     assert('$sour_group->can( "sing" )');
     assert('$lemon_group->can( "sing" )');
     // ... or id
     assert('!$fruits_group->can( $sing_capability_id )');
     assert('!$sweet_group->can( $sing_capability_id )');
     assert('!$banana_group->can( $sing_capability_id )');
     assert('$sour_group->can( $sing_capability_id )');
     assert('$lemon_group->can( $sing_capability_id )');
     // no group can clap
     assert('!$fruits_group->can( $clap_capability_id )');
     assert('!$sweet_group->can( $clap_capability_id )');
     assert('!$banana_group->can( $clap_capability_id )');
     assert('!$sour_group->can( $clap_capability_id )');
     assert('!$lemon_group->can( $clap_capability_id )');
     // user capabilities
     $foo = new Groups_User($foo_user_id);
     $dol = new Groups_User($dol_user_id);
     $baz = new Groups_User($baz_user_id);
     $bar = new Groups_User($bar_user_id);
     assert('$foo->can( "dance" )');
     assert('$dol->can( "dance" )');
     assert('$baz->can( "dance" )');
     assert('$bar->can( "dance" )');
     assert('$foo->can( $dance_capability_id )');
     assert('$dol->can( $dance_capability_id )');
     assert('$baz->can( $dance_capability_id )');
     assert('$bar->can( $dance_capability_id )');
     assert('!$foo->can( "sing" )');
     assert('!$dol->can( "sing" )');
     assert('!$baz->can( "sing" )');
     assert('$bar->can( "sing" )');
     assert('!$foo->can( $sing_capability_id )');
     assert('!$dol->can( $sing_capability_id )');
     assert('!$baz->can( $sing_capability_id )');
     assert('$bar->can( $sing_capability_id )');
     // only foo & baz can clap
     assert('$foo->can( "clap" )');
     assert('!$dol->can( "clap" )');
     assert('$baz->can( "clap" )');
     assert('!$bar->can( "clap" )');
     assert('$foo->can( $clap_capability_id )');
     assert('!$dol->can( $clap_capability_id )');
     assert('$baz->can( $clap_capability_id )');
     assert('!$bar->can( $clap_capability_id )');
     // user can not what is not defined
     assert('!$foo->can( null )');
     assert('!$dol->can( null )');
     assert('!$baz->can( null )');
     assert('!$bar->can( null )');
     assert('!$foo->can( "bogus" )');
     assert('!$dol->can( "bogus" )');
     assert('!$baz->can( "bogus" )');
     assert('!$bar->can( "bogus" )');
     // groups can not what is not defined
     assert('!$fruits_group->can( null )');
     assert('!$sweet_group->can( null )');
     assert('!$banana_group->can( null )');
     assert('!$sour_group->can( null )');
     assert('!$lemon_group->can( null )');
     assert('!$fruits_group->can( "bogus" )');
     assert('!$sweet_group->can( "bogus" )');
     assert('!$banana_group->can( "bogus" )');
     assert('!$sour_group->can( "bogus" )');
     assert('!$lemon_group->can( "bogus" )');
     // test WordPress capabilities
     $administrator = new Groups_User(1);
     assert('$administrator->can( "activate_plugins" )');
     if ($editor_user_id) {
         $editor = new Groups_User($editor_user_id);
         assert('$editor->can( "edit_posts" )');
         assert('!$editor->can( "activate_plugins" )');
     }
     if (is_multisite()) {
         //			 $randext = rand( 0, 100 );
         //			 $wpmu_test_user_id = wp_create_user( 'wpmu_test_user' . $randext, 'wpmu_test_user' );
         //			 assert( '$wpmu_test_user_id instanceof WP_Error === false');
         // @todo create a blog => must create new tables
         //			 wpmu_create_blog( "groups_wpmu_" . $randext, "groups_wpmu_" . $randext, "Groups WPMU Test", $wpmu_test_user_id );
         // @todo add user to new blog
         // @todo switch to new blog
         // @todo check that new user is in "Registered" group
         // @todo switch to current blog
     }
     //
     // PART 2 : delete test data
     //
     if (is_multisite()) {
         // @todo delete new blog
     }
     // remove capabilities from groups
     assert('Groups_Group_Capability::delete( $fruits_group_id, $dance_capability_id )');
     // remove users from groups
     assert('Groups_User_Group::delete($foo_user_id, $fruits_group_id)');
     assert('Groups_User_Group::delete($bar_user_id, $lemon_group_id)');
     // baz must be deleted from user_group when banana group is deleted
     // invalid remove user from group
     assert('Groups_User_Group::delete($foo_user_id, $banana_group_id) === false');
     // delete test users
     include_once ABSPATH . '/wp-admin/includes/user.php';
     if ($foo_user_id && !$foo_user_id instanceof WP_Error) {
         assert('wp_delete_user( $foo_user_id ) === true');
     }
     if ($bar_user_id && !$bar_user_id instanceof WP_Error) {
         assert('wp_delete_user( $bar_user_id ) === true');
     }
     if ($dol_user_id && !$dol_user_id instanceof WP_Error) {
         assert('wp_delete_user( $dol_user_id ) === true');
         if ($sweet_group_id) {
             // see above, this user must have been removed from the group upon its deletion
             assert('Groups_User_Group::read( $dol_user_id, $sweet_group_id ) === false');
         }
     }
     if ($editor_user_id && !$editor_user_id instanceof WP_Error) {
         assert('wp_delete_user( $editor_user_id ) === true');
     }
     // fail to delete inexisting capabilities
     assert('Groups_Capability::delete( -1 ) === false');
     // delete valid test capabilities
     if ($sing_capability_id) {
         assert('Groups_Capability::delete( $sing_capability_id ) !== false');
     }
     if ($dance_capability_id) {
         assert('Groups_Capability::delete( $dance_capability_id ) !== false');
     }
     if ($clap_capability_id) {
         assert('Groups_Capability::delete( $clap_capability_id ) !== false');
     }
     // baz shouldn't be able to clap if there's no clapping capability anymore
     if ($baz_user_id && !$baz_user_id instanceof WP_Error) {
         assert('!$baz->can( "clap" )');
     }
     // fail to delete inexisting group
     assert('Groups_Group::delete( -1 ) === false');
     // delete invalid test group if creation was successful
     if ($bogus_group_id) {
         assert('Groups_Group::delete( $bogus_group_id )');
     }
     // delete valid test groups
     if ($fruits_group_id) {
         assert('Groups_Group::delete( $fruits_group_id )');
     }
     if ($sweet_group_id) {
         assert('Groups_Group::delete( $sweet_group_id )');
     }
     if ($sour_group_id) {
         assert('Groups_Group::delete( $sour_group_id )');
     }
     if ($lemon_group_id) {
         assert('Groups_Group::delete( $lemon_group_id )');
     }
     if ($banana_group_id) {
         assert('Groups_Group::delete( $banana_group_id )');
         assert('Groups_User_Group::delete($baz_user_id, $banana_group_id ) === false');
     }
     // this user must not be deleted before as it is used to test that its
     // relationship with the banana group is resolved when the group is deleted
     if ($baz_user_id && !$baz_user_id instanceof WP_Error) {
         assert('wp_delete_user( $baz_user_id ) === true');
     }
 }
 /**
  * Refreshes Groups capabilities based on WordPress capabilities.
  * @return int number of capabilities added
  */
 public static function refresh_capabilities()
 {
     global $wp_roles;
     $capabilities = array();
     $count = 0;
     if (!isset($wp_roles)) {
         // just trigger initialization
         get_role('administrator');
     }
     $roles = $wp_roles->roles;
     if (is_array($roles)) {
         foreach ($roles as $rolename => $atts) {
             if (isset($atts['capabilities']) && is_array($atts['capabilities'])) {
                 foreach ($atts['capabilities'] as $capability => $value) {
                     if (!in_array($capability, $capabilities)) {
                         $capabilities[] = $capability;
                     }
                 }
             }
         }
     }
     foreach ($capabilities as $capability) {
         if (!Groups_Capability::read_by_capability($capability)) {
             Groups_Capability::create(array('capability' => $capability));
             $count++;
         }
     }
     return $count;
 }
 /**
  * Query modifier to take the selected access restriction capability into
  * account.
  * 
  * @param WP_Query $query query object passed by reference
  */
 public static function parse_query(&$query)
 {
     global $pagenow;
     if (is_admin()) {
         if ($pagenow == 'edit.php') {
             // check that we're on the right screen
             $post_type = isset($_GET['post_type']) ? $_GET['post_type'] : 'post';
             $post_types_option = Groups_Options::get_option(Groups_Post_Access::POST_TYPES, array());
             if (!isset($post_types_option[$post_type]['add_meta_box']) || $post_types_option[$post_type]['add_meta_box']) {
                 if (!empty($_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ_POST_CAPABILITY]) && is_array($_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ_POST_CAPABILITY])) {
                     $include_unrestricted = false;
                     if (in_array(self::NOT_RESTRICTED, $_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ_POST_CAPABILITY])) {
                         $include_unrestricted = true;
                     }
                     $capabilities = array();
                     foreach ($_GET[Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ_POST_CAPABILITY] as $capability) {
                         if (Groups_Capability::read_by_capability($capability)) {
                             $capabilities[] = $capability;
                         }
                     }
                     if (!empty($capabilities)) {
                         if ($include_unrestricted) {
                             // meta_query does not handle a conjunction
                             // on the same meta field correctly
                             // (at least not up to WordPress 3.7.1)
                             // 								$query->query_vars['meta_query'] = array (
                             // 									'relation' => 'OR',
                             // 									array (
                             // 										'key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ_POST_CAPABILITY,
                             // 										'value' => $capabilities,
                             // 										'compare' => 'IN'
                             // 									),
                             // 									array (
                             // 										'key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ_POST_CAPABILITY,
                             // 										'compare' => 'NOT EXISTS'
                             // 									)
                             // 								);
                             // we'll limit it to show just unrestricted entries
                             // until the above is solved
                             $query->query_vars['meta_query'] = array(array('key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ_POST_CAPABILITY, 'compare' => 'NOT EXISTS'));
                         } else {
                             $query->query_vars['meta_query'] = array(array('key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ_POST_CAPABILITY, 'value' => $capabilities, 'compare' => 'IN'));
                         }
                     } else {
                         if ($include_unrestricted) {
                             $query->query_vars['meta_query'] = array(array('key' => Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ_POST_CAPABILITY, 'compare' => 'NOT EXISTS'));
                         }
                     }
                 }
             }
         }
     }
 }
/**
 * Handle remove form submission.
 * @return array of deleted capabilities' ids
 */
function groups_admin_capabilities_bulk_remove_submit()
{
    global $wpdb;
    $result = array();
    if (!current_user_can(GROUPS_ADMINISTER_GROUPS)) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    if (!wp_verify_nonce($_POST[GROUPS_ADMIN_GROUPS_ACTION_NONCE], 'admin')) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    $capability_ids = isset($_POST['capability_ids']) ? $_POST['capability_ids'] : null;
    if ($capability_ids) {
        foreach ($capability_ids as $capability_id) {
            $capability = Groups_Capability::read($capability_id);
            if ($capability) {
                if ($capability->capability !== Groups_Post_Access::READ_POST_CAPABILITY) {
                    if (Groups_Capability::delete($capability_id)) {
                        $result[] = $capability->capability_id;
                    }
                }
            }
        }
    }
    return $result;
}
 /**
  * @return array of valid read capabilities for the current or given user
  */
 public static function get_valid_read_caps_for_user($user_id = null)
 {
     $result = array();
     $user = new Groups_User($user_id === null ? get_current_user_id() : $user_id);
     $valid_read_caps = Groups_Options::get_option(Groups_Post_Access::READ_POST_CAPABILITIES, array(Groups_Post_Access::READ_POST_CAPABILITY));
     foreach ($valid_read_caps as $valid_read_cap) {
         if ($capability = Groups_Capability::read_by_capability($valid_read_cap)) {
             if ($user->can($capability->capability)) {
                 $result[] = $valid_read_cap;
             }
         }
     }
     return $result;
 }
 /**
  * Remove capability and its relations.
  * 
  * @param int $capability_id
  * @return capability_id if successful, false otherwise
  */
 public static function delete($capability_id)
 {
     global $wpdb;
     $result = false;
     // avoid nonsense requests
     if ($capability = Groups_Capability::read($capability_id)) {
         $capability_table = _groups_get_tablename('capability');
         // get rid of it
         if ($rows = $wpdb->query($wpdb->prepare("DELETE FROM {$capability_table} WHERE capability_id = %d", Groups_Utility::id($capability_id)))) {
             $result = $capability_id;
             do_action("groups_deleted_capability", $result);
         }
     }
     return $result;
 }
/**
 * Manage capabilities: table of capabilities and add, edit, remove actions.
 */
function groups_admin_capabilities()
{
    global $wpdb;
    $output = '';
    $today = date('Y-m-d', time());
    if (!current_user_can(GROUPS_ADMINISTER_GROUPS)) {
        wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
    }
    //
    // handle actions
    //
    if (isset($_POST['action'])) {
        //  handle action submit - do it
        switch ($_POST['action']) {
            case 'add':
                if (!($capability_id = groups_admin_capabilities_add_submit())) {
                    return groups_admin_capabilities_add();
                } else {
                    $capability = Groups_Capability::read($capability_id);
                    Groups_Admin::add_message(sprintf(__('The <em>%s</em> capability has been created.', GROUPS_PLUGIN_DOMAIN), stripslashes(wp_filter_nohtml_kses($capability->capability))));
                }
                break;
            case 'edit':
                if (!($capability_id = groups_admin_capabilities_edit_submit())) {
                    return groups_admin_capabilities_edit($_POST['capability-id-field']);
                } else {
                    $capability = Groups_Capability::read($capability_id);
                    Groups_Admin::add_message(sprintf(__('The <em>%s</em> capability has been updated.', GROUPS_PLUGIN_DOMAIN), stripslashes(wp_filter_nohtml_kses($capability->capability))));
                }
                break;
            case 'remove':
                if ($capability_id = groups_admin_capabilities_remove_submit()) {
                    Groups_Admin::add_message(__('The capability has been deleted.', GROUPS_PLUGIN_DOMAIN));
                }
                break;
                // bulk actions on groups: capabilities
            // bulk actions on groups: capabilities
            case 'groups-action':
                if (wp_verify_nonce($_POST[GROUPS_ADMIN_GROUPS_ACTION_NONCE], 'admin')) {
                    $capability_ids = isset($_POST['capability_ids']) ? $_POST['capability_ids'] : null;
                    $bulk = isset($_POST['bulk']) ? $_POST['bulk'] : null;
                    if (is_array($capability_ids) && $bulk !== null) {
                        foreach ($capability_ids as $capability_id) {
                            $bulk_action = isset($_POST['bulk-action']) ? $_POST['bulk-action'] : null;
                            switch ($bulk_action) {
                                case 'remove':
                                    if (isset($_POST['confirm'])) {
                                        groups_admin_capabilities_bulk_remove_submit();
                                    } else {
                                        return groups_admin_capabilities_bulk_remove();
                                    }
                                    break;
                            }
                            break;
                        }
                    }
                }
                break;
        }
    } else {
        if (isset($_GET['action'])) {
            // handle action request - show form
            switch ($_GET['action']) {
                case 'add':
                    return groups_admin_capabilities_add();
                    break;
                case 'edit':
                    if (isset($_GET['capability_id'])) {
                        return groups_admin_capabilities_edit($_GET['capability_id']);
                    }
                    break;
                case 'remove':
                    if (isset($_GET['capability_id'])) {
                        return groups_admin_capabilities_remove($_GET['capability_id']);
                    }
                    break;
                case 'refresh':
                    if (check_admin_referer('refresh')) {
                        $n = Groups_WordPress::refresh_capabilities();
                        if ($n > 0) {
                            $output .= '<div class="info">' . sprintf(_n('One capability has been added.', '%d capabilities have been added.', $n, GROUPS_PLUGIN_DOMAIN), $n) . '</div>';
                        } else {
                            $output .= '<div class="info">' . __('No new capabilities have been found.', GROUPS_PLUGIN_DOMAIN) . '</div>';
                        }
                    } else {
                        wp_die(__('A Duck!', GROUPS_PLUGIN_DOMAIN));
                    }
                    break;
            }
        }
    }
    //
    // capabilities table
    //
    if (isset($_POST['clear_filters']) || isset($_POST['capability_id']) || isset($_POST['capability'])) {
        if (!wp_verify_nonce($_POST[GROUPS_ADMIN_CAPABILITIES_FILTER_NONCE], 'admin')) {
            wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
        }
    }
    // filters
    $capability_id = Groups_Options::get_user_option('capabilities_capability_id', null);
    $capability = Groups_Options::get_user_option('capabilities_capability', null);
    if (isset($_POST['clear_filters'])) {
        Groups_Options::delete_user_option('capabilities_capability_id');
        Groups_Options::delete_user_option('capabilities_capability');
        $capability_id = null;
        $capability = null;
    } else {
        if (isset($_POST['submitted'])) {
            // filter by name
            if (!empty($_POST['capability'])) {
                $capability = $_POST['capability'];
                Groups_Options::update_user_option('capabilities_capability', $capability);
            }
            // filter by capability id
            if (!empty($_POST['capability_id'])) {
                $capability_id = intval($_POST['capability_id']);
                Groups_Options::update_user_option('capabilities_capability_id', $capability_id);
            } else {
                if (isset($_POST['capability_id'])) {
                    // empty && isset => '' => all
                    $capability_id = null;
                    Groups_Options::delete_user_option('capabilities_capability_id');
                }
            }
        }
    }
    if (isset($_POST['row_count'])) {
        if (!wp_verify_nonce($_POST[GROUPS_ADMIN_CAPABILITIES_NONCE_1], 'admin')) {
            wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
        }
    }
    if (isset($_POST['paged'])) {
        if (!wp_verify_nonce($_POST[GROUPS_ADMIN_CAPABILITIES_NONCE_2], 'admin')) {
            wp_die(__('Access denied.', GROUPS_PLUGIN_DOMAIN));
        }
    }
    $current_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $current_url = remove_query_arg('paged', $current_url);
    $current_url = remove_query_arg('action', $current_url);
    $current_url = remove_query_arg('capability_id', $current_url);
    $capability_table = _groups_get_tablename('capability');
    $output .= '<div class="manage-capabilities">' . '<div>' . '<h1>' . __('Capabilities', GROUPS_PLUGIN_DOMAIN) . '</h1>' . '</div>';
    $output .= Groups_Admin::render_messages();
    $output .= '<div class="manage">' . "<a title='" . __('Click to add a new capability', GROUPS_PLUGIN_DOMAIN) . "' class='add button' href='" . esc_url($current_url) . "&action=add'><img class='icon' alt='" . __('Add', GROUPS_PLUGIN_DOMAIN) . "' src='" . GROUPS_PLUGIN_URL . "images/add.png'/><span class='label'>" . __('New Capability', GROUPS_PLUGIN_DOMAIN) . "</span></a>" . "<a title='" . __('Click to refresh capabilities', GROUPS_PLUGIN_DOMAIN) . "' class='refresh button' href='" . esc_url(wp_nonce_url($current_url, 'refresh')) . "&action=refresh'><img class='icon' alt='" . __('Refresh', GROUPS_PLUGIN_DOMAIN) . "' src='" . GROUPS_PLUGIN_URL . "images/refresh.png'/><span class='label'></span></a>" . '</div>';
    $row_count = isset($_POST['row_count']) ? intval($_POST['row_count']) : 0;
    if ($row_count <= 0) {
        $row_count = Groups_Options::get_user_option('capabilities_per_page', GROUPS_CAPABILITIES_PER_PAGE);
    } else {
        Groups_Options::update_user_option('capabilities_per_page', $row_count);
    }
    $offset = isset($_GET['offset']) ? intval($_GET['offset']) : 0;
    if ($offset < 0) {
        $offset = 0;
    }
    $paged = isset($_REQUEST['paged']) ? intval($_REQUEST['paged']) : 0;
    if ($paged < 0) {
        $paged = 0;
    }
    $orderby = isset($_GET['orderby']) ? $_GET['orderby'] : null;
    switch ($orderby) {
        case 'capability_id':
        case 'capability':
            break;
        default:
            $orderby = 'name';
    }
    $order = isset($_GET['order']) ? $_GET['order'] : null;
    switch ($order) {
        case 'asc':
        case 'ASC':
            $switch_order = 'DESC';
            break;
        case 'desc':
        case 'DESC':
            $switch_order = 'ASC';
            break;
        default:
            $order = 'ASC';
            $switch_order = 'DESC';
    }
    $filters = array(" 1=%d ");
    $filter_params = array(1);
    if ($capability_id) {
        $filters[] = " {$capability_table}.capability_id = %d ";
        $filter_params[] = $capability_id;
    }
    if ($capability) {
        $filters[] = " {$capability_table}.capability LIKE '%%%s%%' ";
        $filter_params[] = $capability;
    }
    if (!empty($filters)) {
        $filters = " WHERE " . implode(" AND ", $filters);
    } else {
        $filters = '';
    }
    $count_query = $wpdb->prepare("SELECT COUNT(*) FROM {$capability_table} {$filters}", $filter_params);
    $count = $wpdb->get_var($count_query);
    if ($count > $row_count) {
        $paginate = true;
    } else {
        $paginate = false;
    }
    $pages = ceil($count / $row_count);
    if ($paged > $pages) {
        $paged = $pages;
    }
    if ($paged != 0) {
        $offset = ($paged - 1) * $row_count;
    }
    $query = $wpdb->prepare("SELECT * FROM {$capability_table}\n\t\t{$filters}\n\t\tORDER BY {$orderby} {$order}\n\t\tLIMIT {$row_count} OFFSET {$offset}", $filter_params);
    $results = $wpdb->get_results($query, OBJECT);
    $column_display_names = array('capability_id' => __('Id', GROUPS_PLUGIN_DOMAIN), 'capability' => __('Capability', GROUPS_PLUGIN_DOMAIN), 'description' => __('Description', GROUPS_PLUGIN_DOMAIN), 'edit' => __('Edit', GROUPS_PLUGIN_DOMAIN), 'remove' => __('Remove', GROUPS_PLUGIN_DOMAIN));
    $output .= '<div class="capabilities-overview">';
    $output .= '<div class="filters">' . '<label class="description" for="setfilters">' . __('Filters', GROUPS_PLUGIN_DOMAIN) . '</label>' . '<form id="setfilters" action="" method="post">' . '<p>' . '<label class="capability-id-filter" for="capability_id">' . __('Capability Id', GROUPS_PLUGIN_DOMAIN) . '</label>' . '<input class="capability-id-filter" name="capability_id" type="text" value="' . esc_attr($capability_id) . '"/>' . '<label class="capability-filter" for="capability">' . __('Capability', GROUPS_PLUGIN_DOMAIN) . '</label>' . '<input class="capability-filter" name="capability" type="text" value="' . $capability . '"/>' . '</p>' . '<p>' . wp_nonce_field('admin', GROUPS_ADMIN_CAPABILITIES_FILTER_NONCE, true, false) . '<input class="button" type="submit" value="' . __('Apply', GROUPS_PLUGIN_DOMAIN) . '"/>' . '<input class="button" type="submit" name="clear_filters" value="' . __('Clear', GROUPS_PLUGIN_DOMAIN) . '"/>' . '<input type="hidden" value="submitted" name="submitted"/>' . '</p>' . '</form>' . '</div>';
    if ($paginate) {
        require_once GROUPS_CORE_LIB . '/class-groups-pagination.php';
        $pagination = new Groups_Pagination($count, null, $row_count);
        $output .= '<form id="posts-filter" method="post" action="">';
        $output .= '<div>';
        $output .= wp_nonce_field('admin', GROUPS_ADMIN_CAPABILITIES_NONCE_2, true, false);
        $output .= '</div>';
        $output .= '<div class="tablenav top">';
        $output .= $pagination->pagination('top');
        $output .= '</div>';
        $output .= '</form>';
    }
    $output .= '<div class="page-options right">';
    $output .= '<form id="setrowcount" action="" method="post">';
    $output .= '<div>';
    $output .= '<label for="row_count">' . __('Results per page', GROUPS_PLUGIN_DOMAIN) . '</label>';
    $output .= '<input name="row_count" type="text" size="2" value="' . esc_attr($row_count) . '" />';
    $output .= wp_nonce_field('admin', GROUPS_ADMIN_CAPABILITIES_NONCE_1, true, false);
    $output .= '<input class="button" type="submit" value="' . __('Apply', GROUPS_PLUGIN_DOMAIN) . '"/>';
    $output .= '</div>';
    $output .= '</form>';
    $output .= '</div>';
    $output .= '<form id="groups-action" method="post" action="">';
    $output .= '<div class="tablenav top">';
    $output .= '<div class="capabilities-bulk-container">';
    $output .= '<div class="alignleft actions">';
    $output .= '<select name="bulk-action">';
    $output .= '<option selected="selected" value="-1">' . __("Bulk Actions", GROUPS_PLUGIN_DOMAIN) . '</option>';
    $output .= '<option value="remove">' . __("Remove", GROUPS_PLUGIN_DOMAIN) . '</option>';
    $output .= '</select>';
    $output .= '<input class="button" type="submit" name="bulk" value="' . __("Apply", GROUPS_PLUGIN_DOMAIN) . '"/>';
    $output .= '</div>';
    $output .= '</div>';
    $output .= '</div>';
    $output .= wp_nonce_field('admin', GROUPS_ADMIN_GROUPS_ACTION_NONCE, true, false);
    $output .= '<input type="hidden" name="action" value="groups-action"/>';
    $output .= '<table id="" class="wp-list-table widefat fixed" cellspacing="0">';
    $output .= '<thead>';
    $output .= '<tr>';
    $output .= '<th id="cb" class="manage-column column-cb check-column" scope="col"><input type="checkbox"></th>';
    foreach ($column_display_names as $key => $column_display_name) {
        $options = array('orderby' => $key, 'order' => $switch_order);
        $class = $key;
        if (!in_array($key, array('capabilities', 'edit', 'remove'))) {
            if (strcmp($key, $orderby) == 0) {
                $lorder = strtolower($order);
                $class = "{$key} manage-column sorted {$lorder}";
            } else {
                $class = "{$key} manage-column sortable";
            }
            $column_display_name = '<a href="' . esc_url(add_query_arg($options, $current_url)) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
        }
        $output .= "<th scope='col' class='{$class}'>{$column_display_name}</th>";
    }
    $output .= '</tr>
		</thead>
		<tbody>
		';
    if (count($results) > 0) {
        for ($i = 0; $i < count($results); $i++) {
            $result = $results[$i];
            $output .= '<tr class="' . ($i % 2 == 0 ? 'even' : 'odd') . '">';
            $output .= '<th class="check-column">';
            $output .= '<input type="checkbox" value="' . esc_attr($result->capability_id) . '" name="capability_ids[]"/>';
            $output .= '</th>';
            $output .= "<td class='capability-id'>";
            $output .= $result->capability_id;
            $output .= "</td>";
            $output .= "<td class='capability'>" . stripslashes(wp_filter_nohtml_kses($result->capability)) . "</td>";
            $output .= "<td class='description'>" . stripslashes(wp_filter_nohtml_kses($result->description)) . "</td>";
            $output .= "<td class='edit'>";
            $output .= "<a href='" . esc_url(add_query_arg('paged', $paged, $current_url)) . "&action=edit&capability_id=" . $result->capability_id . "' alt='" . __('Edit', GROUPS_PLUGIN_DOMAIN) . "'><img src='" . GROUPS_PLUGIN_URL . "images/edit.png'/></a>";
            $output .= "</td>";
            $output .= "<td class='remove'>";
            if ($result->capability !== Groups_Post_Access::READ_POST_CAPABILITY) {
                $output .= "<a href='" . esc_url($current_url) . "&action=remove&capability_id=" . $result->capability_id . "' alt='" . __('Remove', GROUPS_PLUGIN_DOMAIN) . "'><img src='" . GROUPS_PLUGIN_URL . "images/remove.png'/></a>";
            }
            $output .= "</td>";
            $output .= '</tr>';
        }
    } else {
        $output .= '<tr><td colspan="6">' . __('There are no results.', GROUPS_PLUGIN_DOMAIN) . '</td></tr>';
    }
    $output .= '</tbody>';
    $output .= '</table>';
    $output .= Groups_UIE::render_add_titles('.capabilities-overview table td');
    $output .= '</form>';
    // #groups-action
    if ($paginate) {
        require_once GROUPS_CORE_LIB . '/class-groups-pagination.php';
        $pagination = new Groups_Pagination($count, null, $row_count);
        $output .= '<div class="tablenav bottom">';
        $output .= $pagination->pagination('bottom');
        $output .= '</div>';
    }
    $output .= '</div>';
    // .capabilities-overview
    $output .= '</div>';
    // .manage-capabilities
    echo $output;
    Groups_Help::footer();
}
 /**
  * Renders custom column content.
  * 
  * @param string $column_name
  * @param int $post_id
  * @return string custom column content
  */
 public static function custom_column($column_name, $post_id)
 {
     $output = '';
     switch ($column_name) {
         case self::CAPABILITIES:
             $read_caps = get_post_meta($post_id, Groups_Post_Access::POSTMETA_PREFIX . Groups_Post_Access::READ_POST_CAPABILITY);
             $valid_read_caps = Groups_Options::get_option(Groups_Post_Access::READ_POST_CAPABILITIES, array(Groups_Post_Access::READ_POST_CAPABILITY));
             if (count($valid_read_caps) > 0) {
                 sort($valid_read_caps);
                 $output = '<ul>';
                 foreach ($valid_read_caps as $valid_read_cap) {
                     if ($capability = Groups_Capability::read_by_capability($valid_read_cap)) {
                         if (in_array($valid_read_cap, $read_caps)) {
                             $output .= '<li>';
                             $output .= wp_strip_all_tags($capability->capability);
                             $output .= '</li>';
                         }
                     }
                 }
                 $output .= '</ul>';
             } else {
                 $output .= '';
             }
             break;
     }
     echo $output;
 }