/**
 * 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();
}
 /**
  * Hooks into the remove_user_from_blog action to remove the user
  * from groups that belong to that blog.
  * 
  *  Note that this is preemptive as there is no
  *  removed_user_from_blog action.
  * 
  * @param int $user_id
  * @param int $blog_id
  */
 public static function remove_user_from_blog($user_id, $blog_id)
 {
     if (is_multisite()) {
         Groups_Controller::switch_to_blog($blog_id);
     }
     global $wpdb;
     $group_table = _groups_get_tablename("group");
     $user_group_table = _groups_get_tablename("user_group");
     // We can end up here while a blog is being deleted, in that case,
     // the tables have already been deleted.
     if ($wpdb->get_var("SHOW TABLES LIKE '" . $group_table . "'") == $group_table && $wpdb->get_var("SHOW TABLES LIKE '" . $user_group_table . "'") == $user_group_table) {
         $rows = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$user_group_table}\n\t\t\t\tLEFT JOIN {$group_table} ON {$user_group_table}.group_id = {$group_table}.group_id\n\t\t\t\tWHERE {$user_group_table}.user_id = %d\n\t\t\t\t", Groups_Utility::id($user_id)));
         if ($rows) {
             foreach ($rows as $row) {
                 // don't optimize that, favour standard deletion
                 self::delete($row->user_id, $row->group_id);
             }
         }
     }
     if (is_multisite()) {
         Groups_Controller::restore_current_blog();
     }
 }
 /**
  * Plugin activation work.
  */
 private static function setup()
 {
     global $wpdb, $wp_roles;
     // create WP capabilities
     Groups_Controller::set_default_capabilities();
     $charset_collate = '';
     if (!empty($wpdb->charset)) {
         $charset_collate = "DEFAULT CHARACTER SET {$wpdb->charset}";
     }
     if (!empty($wpdb->collate)) {
         $charset_collate .= " COLLATE {$wpdb->collate}";
     }
     // create tables
     $group_table = _groups_get_tablename('group');
     if ($wpdb->get_var("SHOW TABLES LIKE '{$group_table}'") != $group_table) {
         $queries[] = "CREATE TABLE {$group_table} (\n\t\t\t\tgroup_id     BIGINT(20) UNSIGNED NOT NULL auto_increment,\n\t\t\t\tparent_id    BIGINT(20) DEFAULT NULL,\n\t\t\t\tcreator_id   BIGINT(20) DEFAULT NULL,\n\t\t\t\tdatetime     DATETIME DEFAULT NULL,\n\t\t\t\tname         VARCHAR(100) NOT NULL,\n\t\t\t\tdescription  LONGTEXT DEFAULT NULL,\n\t\t\t\tPRIMARY KEY  (group_id),\n\t\t\t\tUNIQUE INDEX group_n (name)\n\t\t\t) {$charset_collate};";
     }
     $capability_table = _groups_get_tablename('capability');
     if ($wpdb->get_var("SHOW TABLES LIKE '{$capability_table}'") != $capability_table) {
         $queries[] = "CREATE TABLE {$capability_table} (\n\t\t\t\tcapability_id BIGINT(20) UNSIGNED NOT NULL auto_increment,\n\t\t\t\tcapability    VARCHAR(255) NOT NULL,\n\t\t\t\tclass         VARCHAR(255) DEFAULT NULL,\n\t\t\t\tobject        VARCHAR(255) DEFAULT NULL,\n\t\t\t\tname          VARCHAR(100) DEFAULT NULL,\n\t\t\t\tdescription   LONGTEXT DEFAULT NULL,\n\t\t\t\tPRIMARY KEY   (capability_id),\n\t\t\t\tUNIQUE INDEX  capability (capability(100)),\n\t\t\t\tINDEX         capability_kco (capability(20),class(20),object(20))\n\t\t\t) {$charset_collate};";
     }
     $user_group_table = _groups_get_tablename('user_group');
     if ($wpdb->get_var("SHOW TABLES LIKE '{$user_group_table}'") != $user_group_table) {
         $queries[] = "CREATE TABLE {$user_group_table} (\n\t\t\t\tuser_id     bigint(20) unsigned NOT NULL,\n\t\t\t\tgroup_id    bigint(20) unsigned NOT NULL,\n\t\t\t\tPRIMARY KEY (user_id, group_id),\n\t\t\t\tINDEX       user_group_gu (group_id,user_id)\n\t\t\t) {$charset_collate};";
     }
     $user_capability_table = _groups_get_tablename('user_capability');
     if ($wpdb->get_var("SHOW TABLES LIKE '{$user_capability_table}'") != $user_capability_table) {
         $queries[] = "CREATE TABLE {$user_capability_table} (\n\t\t\t\tuser_id\t      bigint(20) unsigned NOT NULL,\n\t\t\t\tcapability_id bigint(20) unsigned NOT NULL,\n\t\t\t\tPRIMARY KEY   (user_id, capability_id),\n\t\t\t\tINDEX         user_capability_cu (capability_id,user_id)\n\t\t\t) {$charset_collate};";
     }
     $group_capability_table = _groups_get_tablename('group_capability');
     if ($wpdb->get_var("SHOW TABLES LIKE '{$group_capability_table}'") != $group_capability_table) {
         $queries[] = "CREATE TABLE {$group_capability_table} (\n\t\t\t\tgroup_id      bigint(20) unsigned NOT NULL,\n\t\t\t\tcapability_id bigint(20) unsigned NOT NULL,\n\t\t\t\tPRIMARY KEY   (group_id, capability_id),\n\t\t\t\tINDEX         group_capability_cg (capability_id,group_id)\n\t\t\t) {$charset_collate};";
     }
     if (!empty($queries)) {
         require_once ABSPATH . 'wp-admin/includes/upgrade.php';
         dbDelta($queries);
     }
     // needs to be called to create its capabilities
     Groups_Post_Access::activate();
     // same thing to created groups for registered users
     Groups_Registered::activate();
     // add WordPress capabilities
     Groups_WordPress::activate();
     // ... end of plugin activation work.
 }
 /**
  * Assign a user to its "Registered" group for the given blog.
  * 
  * @param int $user_id
  * @param WP_string $role
  */
 function add_user_to_blog($user_id, $role, $blog_id)
 {
     if (is_multisite()) {
         Groups_Controller::switch_to_blog($blog_id);
     }
     global $wpdb;
     // Check if the group table exists, if it does not exist, we are
     // probably here because the action has been triggered in the middle
     // of wpmu_create_blog() before the wpmu_new_blog action has been
     // triggered. In that case, just skip this as the user will be added
     // later when wpmu_new_blog is triggered, the activation sequence has
     // created the tables and all users of the new blog are added to
     // that blog's "Registered" group.
     $group_table = _groups_get_tablename('group');
     if ($wpdb->get_var("SHOW TABLES LIKE '" . $group_table . "'") == $group_table) {
         $registered_group = Groups_Group::read_by_name(self::REGISTERED_GROUP_NAME);
         if (!$registered_group) {
             $registered_group_id = Groups_Group::create(array("name" => self::REGISTERED_GROUP_NAME));
         } else {
             $registered_group_id = $registered_group->group_id;
         }
         if ($registered_group_id) {
             Groups_User_Group::create(array('user_id' => $user_id, 'group_id' => $registered_group_id));
         }
     }
     if (is_multisite()) {
         Groups_Controller::restore_current_blog();
     }
 }