Members - Version 0.1

Version Description

Download this release

Release Info

Developer greenshady
Plugin Icon 128x128 Members
Version 0.1
Comparing to
See all releases

Version 0.1

components.php ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Members Components API. This file contains everything you need to build custom components.
4
+ * Rather than limiting the plugin to self-contained settings, the Components API was created so
5
+ * that it could be extended by other plugins and themes. Registering a component is as simple as
6
+ * using the registration function and creating a custom callback function for the component.
7
+ *
8
+ * To register a component, use the register_component() function. When registering a custom
9
+ * component, your registration function should be hooked to 'members_register_components'.
10
+ *
11
+ * @package Members
12
+ * @subpackage Components
13
+ */
14
+
15
+ /* Register the default components shippedd with the plugin. */
16
+ add_action( 'init', 'members_create_default_components', 0 );
17
+
18
+ /* Load the callback functions for each of the registered components. Components should be registered on 'init' with a priority less than '10'. */
19
+ add_action( 'init', 'members_load_components', 0 );
20
+
21
+ /**
22
+ * Registers the initial components packaged with the plugin.
23
+ * @uses register_members_component() Registers a component.
24
+ *
25
+ * @since 0.1
26
+ */
27
+ function members_create_default_components() {
28
+ register_members_component( array( 'name' => 'edit_roles', 'label' => __('Edit Roles', 'members'), 'callback' => 'members_component_edit_roles', 'requires' => false, 'description' => __('The <em>Edit Roles</em> component allows you to manage all roles on your site. You can change which capabilities individual roles have. Once you\'ve selected this component, you should immediately give at least one role the <code>edit_roles</code> capability. This makes sure only the roles you select can edit roles.', 'members') ) );
29
+ register_members_component( array( 'name' => 'new_roles', 'label' => __('New Roles', 'members'), 'callback' => 'members_component_new_roles', 'requires' => false, 'description' => __('The <em>New Roles</em> component allows you to create new roles on your site. To use this component, you must have the <code>create_roles</code> capability. This makes sure only the roles you select can create new roles.', 'members') ) );
30
+ register_members_component( array( 'name' => 'content_permissions', 'label' => __('Content Permissions', 'members'), 'callback' => 'members_component_content_permissions', 'requires' => false, 'description' => __('Adds an additional meta box for the post/page editor that allows you to grant permissions for who can read the content based on the the user\'s capabilities or role. Only roles with the <code>restrict_content</code> capability will be able to use this component.', 'members') ) );
31
+ register_members_component( array( 'name' => 'shortcodes', 'label' => __('Shortcodes', 'members'), 'callback' => 'members_component_shortcodes', 'requires' => false, 'description' => __('Provides a set of shortcodes that may be used to restrict or provide access to certain areas of your site from within the post editor (or other areas where shortcodes are allowed).', 'members') ) );
32
+ register_members_component( array( 'name' => 'template_tags', 'label' => __('Template Tags', 'members'), 'callback' => 'members_component_template_tags', 'requires' => false, 'description' => __('Provides additional template tags for use within your WordPress theme for restricting or providing access to certain content.', 'members') ) );
33
+ register_members_component( array( 'hook' => 'widgets_init', 'name' => 'widgets', 'label' => __('Widgets', 'members'), 'callback' => 'members_component_widgets', 'requires' => false, 'description' => __('Creates additional widgets for use in any widget area on your site. The current widgets are Login Form and Users.', 'members') ) );
34
+ register_members_component( array( 'name' => 'private_blog', 'label' => __('Private Blog', 'members'), 'callback' => 'members_component_private_blog', 'requires' => false, 'description' => __('Forces all users to log into the site before viewing it. It will always redirect users to the login page. Note that this component does not block public access to your feeds.', 'members') ) );
35
+ //register_members_component( array( 'name' => 'user_fields', 'label' => __('User Fields', 'members'), 'callback' => 'members_component_user_fields', 'requires' => false, 'description' => __('Provides an interface for building additional user profile fields. Users will then be able provide this additional information when editing their profile', 'members') ) );
36
+
37
+ do_action( 'members_register_components' ); // Available hook to register components.
38
+ }
39
+
40
+ /**
41
+ * Function for registering an additional component for the plugin, which the user
42
+ * may choose to use. Note that you should add in all the arguments to properly register
43
+ * your component. The exception is $requires.
44
+ *
45
+ * Your callback function should make use of the is_active_members_component() function
46
+ * as soon as it fires. This allows you to check if the user has activated the component before
47
+ * loading all of your code. Please use this system as it keeps the plugin as light as possible.
48
+ *
49
+ * @since 0.1
50
+ * @global $members object The global members object.
51
+ *
52
+ * @param $args array Arguments for registering a custom component.
53
+ * @param $args[$name] string Name of the component (only letters, numbers, and spaces).
54
+ * @param $args[$label] string Display name of the component.
55
+ * @param $args[$description] string Description of the component.
56
+ * @param $args[$callback] string Function that will be called when the components system is loaded.
57
+ * @param $args[$requires] array|bool Names of other components that are required to run this component.
58
+ */
59
+ function register_members_component( $args = array() ) {
60
+ global $members;
61
+
62
+ $name = $args['name'];
63
+
64
+ $members->registered_components[$name] = (object)$args;
65
+ }
66
+
67
+ /**
68
+ * Loops through the registered components and load the necessary callback function.
69
+ * If a $component->hook is added and a $component->callback function, the plugin
70
+ * will add the function to the action hook automatically. Else if the $component->callback
71
+ * function exists but not $component->hook, the function will simply be called.
72
+ *
73
+ * @since 0.2
74
+ * @global $members object The global members object.
75
+ */
76
+ function members_load_components() {
77
+ global $members;
78
+
79
+ /* Check if there are any registered components. If not, return false. */
80
+ if ( !is_array( $members->registered_components ) )
81
+ return false;
82
+
83
+ /* Loop through each of the registered components and execute the desired action. */
84
+ foreach ( $members->registered_components as $component ) {
85
+
86
+ /* If a callback function has been input, continue the process. */
87
+ if ( $component->callback && function_exists( $component->callback ) ) {
88
+
89
+ /* If a hook has been input, add the component callback function to the action hook. */
90
+ if ( $component->hook )
91
+ add_action( $component->hook, $component->callback );
92
+
93
+ /* Call the function directly if there is no hook. */
94
+ else
95
+ call_user_func( $component->callback, $component );
96
+ }
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Function for getting a specific component object from the list of registered
102
+ * plugin components.
103
+ *
104
+ * @since 0.1
105
+ * @global $members object The global members object.
106
+ * @param $component string Required. The name of the component.
107
+ * @return $members->registered_components[$component] object
108
+ */
109
+ function get_members_component( $component ) {
110
+ global $members;
111
+ return $members->registered_components[$component_name];
112
+ }
113
+
114
+ /**
115
+ * Checks if a component has been activated by the user. If it has, return true. If not,
116
+ * return false.
117
+ * @todo Add the activated state to the $members_components variable instead of making
118
+ * a completely new global variable with $members_components_active.
119
+ *
120
+ * @since 0.1
121
+ * @global $members object The global members object.
122
+ * @param $component string Name of the component to check for.
123
+ * @return true|false bool
124
+ */
125
+ function is_active_members_component( $component = '' ) {
126
+ global $members;
127
+
128
+ if ( !$component )
129
+ return false;
130
+
131
+ if ( !is_array( $members->active_components ) )
132
+ $members->active_components = get_option( 'members_settings' );
133
+
134
+ return $members->active_components[$component];
135
+ }
136
+
137
+ /* Default Components */
138
+
139
+ /**
140
+ * Manage roles component. This allows you to manage each role's set
141
+ * of capabilities.
142
+ *
143
+ * @since 0.1
144
+ */
145
+ function members_component_edit_roles() {
146
+ if ( is_admin() && is_active_members_component( 'edit_roles' ) ) {
147
+ require_once( MEMBERS_COMPONENTS . '/edit-roles/default.php' );
148
+ add_action( 'admin_menu', 'members_component_load_edit_roles' );
149
+ }
150
+ }
151
+
152
+ /**
153
+ * New roles component. This allows you to create new roles.
154
+ *
155
+ * @since 0.1
156
+ */
157
+ function members_component_new_roles() {
158
+ if ( is_admin() && is_active_members_component( 'new_roles' ) ) {
159
+ require_once( MEMBERS_COMPONENTS . '/new-roles/default.php' );
160
+ add_action( 'admin_menu', 'members_component_load_new_roles' );
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Loads the content permissions component.
166
+ *
167
+ * @since 0.1
168
+ */
169
+ function members_component_content_permissions() {
170
+ if ( is_active_members_component( 'content_permissions' ) ) {
171
+ require_once( MEMBERS_COMPONENTS . '/content-permissions/content-permissions.php' );
172
+ require_once( MEMBERS_COMPONENTS . '/content-permissions/meta-box.php' );
173
+ add_action( 'admin_menu', 'members_content_permissions_create_meta_box' );
174
+ add_action( 'save_post', 'members_content_permissions_save_meta', 1, 2 );
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Loads the shortcodes component.
180
+ *
181
+ * @since 0.1
182
+ */
183
+ function members_component_shortcodes() {
184
+ if ( !is_admin() && is_active_members_component( 'shortcodes' ) )
185
+ require_once( MEMBERS_COMPONENTS . '/shortcodes/shortcodes.php' );
186
+ }
187
+
188
+ /**
189
+ * Loads the template tags component.
190
+ *
191
+ * @since 0.1
192
+ */
193
+ function members_component_template_tags() {
194
+ if ( is_active_members_component( 'template_tags' ) )
195
+ require_once( MEMBERS_COMPONENTS . '/template-tags/template-tags.php' );
196
+ }
197
+
198
+ /**
199
+ * Loads the widgets component.
200
+ *
201
+ * @since 0.1
202
+ */
203
+ function members_component_widgets() {
204
+ if ( is_active_members_component( 'widgets' ) ) {
205
+
206
+ /* Load each of the widget files. */
207
+ require_once( MEMBERS_COMPONENTS . '/widgets/login.php' );
208
+ require_once( MEMBERS_COMPONENTS . '/widgets/users.php' );
209
+
210
+ /* Register each widget. */
211
+ register_widget( 'Members_Widget_Login' );
212
+ register_widget( 'Members_Widget_Users' );
213
+ }
214
+ }
215
+
216
+ /**
217
+ * Loads the private blog component.
218
+ *
219
+ * @since 0.1
220
+ */
221
+ function members_component_private_blog() {
222
+ if ( is_active_members_component( 'private_blog' ) )
223
+ require_once( MEMBERS_COMPONENTS . '/private-blog/default.php' );
224
+ }
225
+
226
+ /**
227
+ * Loads the user fields component.
228
+ *
229
+ * @internal Do not use this function. The component isn't ready.
230
+ * @todo Pretty much everything.
231
+ *
232
+ * @since 0.1
233
+ */
234
+ function members_component_user_fields() {
235
+ if ( is_admin() && is_active_members_component( 'user_fields' ) )
236
+ require_once( MEMBERS_COMPONENTS . '/user-fields/default.php' );
237
+ }
238
+
239
+ ?>
components/content-permissions/comments.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php /* Life is sweet. */ ?>
components/content-permissions/content-permissions.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Content Permissions component was created so that access to specific parts of a site
4
+ * can be granted or denied. This is the component that gives truly fine-grained control over
5
+ * who can see what content on the front end of the site.
6
+ *
7
+ * Current features of the Content Permissions component:
8
+ * - Block content on a post-by-post (or page) basis according to user role.
9
+ *
10
+ * This feature set should eventually include the ability to block access to taxonomies and
11
+ * attachments to be truly useful.
12
+ *
13
+ * @todo Check and test feeds and filter if necessary.
14
+ * @todo Make sure comments aren't shown anywhere.
15
+ * @todo Remove pages from wp_list_pages() and wp_page_menu().
16
+ * @todo Cover ALL the bases. If something's restricted, make sure it stays that way.
17
+ *
18
+ * @package Members
19
+ * @subpackage Components
20
+ */
21
+
22
+ /* Add messages to the components form. */
23
+ add_action( 'members_pre_components_form', 'members_message_no_restrict_content' );
24
+
25
+ /* Filter the content and exerpts. */
26
+ add_filter( 'the_content', 'members_content_permissions_protect' );
27
+ add_filter( 'get_the_excerpt', 'members_content_permissions_protect' );
28
+ add_filter( 'the_excerpt', 'members_content_permissions_protect' );
29
+
30
+ /* Filter the comments template to make sure comments aren't shown to users without access. */
31
+ add_filter( 'comments_template', 'members_content_permissions_comments' );
32
+
33
+ /**
34
+ * Disables the comments template if the current post has been restricted, unless
35
+ * the user has the role needed to view the content of the post.
36
+ *
37
+ * @todo Allow users to override the "no comments" template if in their theme.
38
+ *
39
+ * @since 0.1
40
+ * @param $template string File URL of the template to display.
41
+ * @return $template string File URL of the template to display.
42
+ */
43
+ function members_content_permissions_comments( $template ) {
44
+ global $wp_query;
45
+
46
+ $roles = get_post_meta( $wp_query->post->ID, '_role', false );
47
+
48
+ if ( is_array( $roles ) ) {
49
+ foreach( $roles as $role ) {
50
+ if ( !is_feed() && ( current_user_can( $role ) || current_user_can( 'restrict_content' ) ) )
51
+ return $template;
52
+ }
53
+ $template = MEMBERS_COMPONENTS . '/content-permissions/comments.php';
54
+ }
55
+ return $template;
56
+ }
57
+
58
+ /**
59
+ * Displays a message if the Content Permissions component is active but no role
60
+ * has been given the capability of 'restrict_content', which is a required capability to
61
+ * use the component.
62
+ *
63
+ * @since 0.1
64
+ * @uses is_active_members_component() Checks if the content_permissions component is active.
65
+ * @uses members_check_form_cap() Checks if the restrict_content capability has been given to a role.
66
+ */
67
+ function members_message_no_restrict_content() {
68
+ if ( is_active_members_component( 'content_permissions' ) && !members_check_for_cap( 'restrict_content' ) ) {
69
+ $message = __('No role currently has the <code>restrict_content</code> capability. To use the <em>Content Permissions</em> component, at least one role must have this capability.', 'members');
70
+ members_admin_message( '', $message );
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Disables content passed through the $content variable given the current user's role. The
76
+ * function checks for a custom field key of "Role" and loops through its values, checking
77
+ * if the current user has that particular role.
78
+ *
79
+ * Users with the rescrict_content capability should also be able to see the content.
80
+ *
81
+ * @since 0.1
82
+ * @uses get_post_meta() Gets the meta values of the "_role" custom field key.
83
+ * @uses current_user_can() Checks if the current user has a particular role (capability).
84
+ * @param $content string The current post's content/excerpt.
85
+ * @return $content string Either the current post's content/excerpt or a content inaccessible message.
86
+ */
87
+ function members_content_permissions_protect( $content ) {
88
+ global $post;
89
+
90
+ $roles = get_post_meta( $post->ID, '_role', false );
91
+
92
+ if ( is_array( $roles ) ) {
93
+ foreach( $roles as $role ) {
94
+ if ( !is_feed() && ( current_user_can( $role ) || current_user_can( 'restrict_content' ) ) )
95
+ return $content;
96
+ }
97
+ $content = '<p class="restricted alert warning">' . __('Sorry, but you do not have permission to view this content.', 'members') . '</p>';
98
+ }
99
+
100
+ return $content;
101
+ }
102
+
103
+ ?>
components/content-permissions/meta-box.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Adds the meta box for the Content Permissions component. This allows users with
4
+ * the 'restrict_content' capability to restrict posts/pages on a post/page basis. Roles
5
+ * with the 'restrict_content' capability should be able to see all content, regardless
6
+ * of the settings.
7
+ *
8
+ * @package Members
9
+ * @subpackage Components
10
+ */
11
+
12
+ /**
13
+ * Adds the meta box to the post/page edit screen if the current user has
14
+ * the 'restrict_content' capability.
15
+ *
16
+ * @since 0.1
17
+ * @uses add_meta_box() Creates an additiona meta box.
18
+ */
19
+ function members_content_permissions_create_meta_box() {
20
+ if ( current_user_can( 'restrict_content' ) ) {
21
+ add_meta_box( 'content-permissions-meta-box', 'Content Permissions', 'members_content_permissions_meta_box', 'post', 'advanced', 'high' );
22
+ add_meta_box( 'content-permissions-meta-box', 'Content Permissions', 'members_content_permissions_meta_box', 'page', 'advanced', 'high' );
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Controls the display of the content permissions meta box. This allows users
28
+ * to select roles that should have access to an individual post/page.
29
+ *
30
+ * @since 0.1
31
+ * @global $post
32
+ * @global $wp_roles
33
+ * @param $object
34
+ * @param $box
35
+ */
36
+ function members_content_permissions_meta_box( $object, $box ) {
37
+ global $post, $wp_roles; ?>
38
+
39
+ <input type="hidden" name="content_permissions_meta_nonce" value="<?php echo wp_create_nonce(plugin_basename(__FILE__)); ?>" />
40
+
41
+ <p>
42
+ <label for="roles"><?php _e('<strong>Roles:</strong> Restrict the content to these roles on the front end of the site. If all boxes are left unchecked, everyone can view the content.', 'members'); ?></label>
43
+ </p>
44
+
45
+ <div style="overflow: hidden;">
46
+
47
+ <?php
48
+
49
+ /* Get the 'Role' meta key. */
50
+ $meta = get_post_meta( $post->ID, '_role', false );
51
+
52
+ /* Loop through each of the available roles. */
53
+ foreach ( $wp_roles->role_names as $role => $name ) {
54
+ $checked = false;
55
+
56
+ /* If the role has been selected, make sure it's checked. */
57
+ if ( is_array( $meta ) && in_array( $role, $meta ) )
58
+ $checked = ' checked="checked" '; ?>
59
+
60
+ <p style="width: 32%; float: left; margin-right: 0;">
61
+ <label for="role-<?php echo $role; ?>">
62
+ <input type="checkbox" name="role[<?php echo $role; ?>]" id="role-<?php echo $role; ?>" <?php echo $checked; ?> value="<?php echo $role; ?>" />
63
+ <?php echo str_replace( '|User role', '', $name ); ?>
64
+ </label>
65
+ </p>
66
+ <?php } ?>
67
+
68
+ </div><?php
69
+ }
70
+
71
+ /**
72
+ * Saves the content permissions metabox data to a custom field.
73
+ *
74
+ * @since 0.1
75
+ */
76
+ function members_content_permissions_save_meta( $post_id, $post ) {
77
+ global $wp_roles;
78
+
79
+ /* Only allow users that can edit the current post to submit data. */
80
+ if ( 'post' == $post->post_type && !current_user_can( 'edit_posts', $post_id ) )
81
+ return;
82
+
83
+ /* Only allow users that can edit the current page to submit data. */
84
+ elseif ( 'page' == $post->post_type && !current_user_can( 'edit_pages', $post_id ) )
85
+ return;
86
+
87
+ /* Don't save if the post is only a revision. */
88
+ if ( 'revision' == $post->post_type )
89
+ return;
90
+
91
+ /* Loop through each of the site's available roles. */
92
+ foreach ( $wp_roles->role_names as $role => $name ) {
93
+
94
+ /* Get post metadata for the custom field key 'Role'. */
95
+ $meta = (array)get_post_meta( $post_id, '_role', false );
96
+
97
+ /* Check if the role was selected. */
98
+ if ( $_POST['role'][$role] ) {
99
+
100
+ /* If selected and already saved, continue looping through the roles and do nothing for this role. */
101
+ if ( in_array( $role, $meta ) )
102
+ continue;
103
+
104
+ /* If the role was seleted and not already saved, add the role as a new value to the 'Role' custom field. */
105
+ else
106
+ $add = add_post_meta( $post_id, '_role', $role, false );
107
+ }
108
+
109
+ /* If role not selected, delete. */
110
+ else
111
+ $delete = delete_post_meta( $post_id, '_role', $role );
112
+
113
+ } // End loop through site's roles.
114
+ }
115
+
116
+ ?>
components/edit-roles/default.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* Actions added by the Edit Roles component. */
4
+ add_action( 'members_pre_components_form', 'members_message_no_edit_roles' );
5
+ add_action( 'members_pre_edit_role_form', 'members_message_no_edit_roles' );
6
+ add_action( 'members_pre_edit_roles_form', 'members_message_no_edit_roles' );
7
+
8
+ /**
9
+ * Message to show when a single role has been deleted.
10
+ * @since 0.1
11
+ */
12
+ function members_message_role_deleted() {
13
+ $message = __('Role deleted.', 'members');
14
+ members_admin_message( '', $message );
15
+ }
16
+
17
+ /**
18
+ * Message to show when multiple roles have been deleted (bulk delete).
19
+ * @since 0.1
20
+ */
21
+ function members_message_roles_deleted() {
22
+ $message = __('Selected roles deleted.', 'members');
23
+ members_admin_message( '', $message );
24
+ }
25
+
26
+ /**
27
+ * Message to show when no role has the 'edit_roles' capability.
28
+ * @since 0.1
29
+ */
30
+ function members_message_no_edit_roles() {
31
+ if ( is_active_members_component( 'edit_roles' ) && !members_check_for_cap( 'edit_roles' ) ) {
32
+ $message = __('No role currently has the <code>edit_roles</code> capability. Please add this to each role that should be able to manage/edit roles. If you do not change this, any user that has the <code>edit_users</code> capability will be able to edit roles.', 'members');
33
+ members_admin_message( '', $message );
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Loads the settings pages for the Manage Roles component.
39
+ * @since 0.1
40
+ */
41
+ function members_component_load_edit_roles() {
42
+ global $members_manage_roles_page;
43
+
44
+ /* Capability to manage roles. Users need to change this on initial setup by giving at least one role the 'edit_roles' capability. */
45
+ if ( members_check_for_cap( 'edit_roles' ) )
46
+ $edit_roles_cap = 'edit_roles';
47
+ else
48
+ $edit_roles_cap = 'edit_users';
49
+
50
+ /* Create the Manage Roles page. */
51
+ $members_edit_roles_page = add_submenu_page( 'users.php', __('Roles', 'members'), __('Roles', 'members'), $edit_roles_cap, 'roles', 'members_edit_roles_page' );
52
+ }
53
+
54
+ /**
55
+ * Loads the Manage Roles page.
56
+ * @since 0.1
57
+ */
58
+ function members_edit_roles_page() {
59
+ require_once( MEMBERS_COMPONENTS . '/edit-roles/manage-roles.php' );
60
+ }
61
+
62
+ ?>
components/edit-roles/edit-role-form.php ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Edit Role form is for editing individual roles. The role to edit must
4
+ * have been selected on the Edit Roles page.
5
+ *
6
+ * @package Members
7
+ * @subpackage Components
8
+ */
9
+
10
+ /* Get the current role object to edit. */
11
+ $role = get_role( $role );
12
+
13
+ /* Check if the form has been submitted. */
14
+ if ( $_POST['edit-role-saved'] == 'Y' ) {
15
+
16
+ /* Verify the nonce. */
17
+ check_admin_referer( members_get_nonce( 'edit-roles' ) );
18
+
19
+ /* Set the $role_updated variable to true. */
20
+ $role_updated = true;
21
+
22
+ /* Loop through all available capabilities. */
23
+ foreach ( members_get_capabilities() as $cap ) {
24
+
25
+ /* Get the posted capability. */
26
+ $posted_cap = $_POST['role-caps']["{$role->name}-{$cap}"];
27
+
28
+ /* If the role doesn't have the capability and it was selected, add it. */
29
+ if ( !$role->has_cap( $cap ) && $posted_cap )
30
+ $role->add_cap( $cap );
31
+
32
+ /* If the role has the capability and it wasn't selected, remove it. */
33
+ elseif ( $role->has_cap( $cap ) && !$posted_cap )
34
+ $role->remove_cap( $cap );
35
+
36
+ } // End loop through existing capabilities
37
+
38
+ /* If new caps were added and are in an array, we need to add them. */
39
+ if ( !empty( $_POST['new-cap'] ) && is_array( $_POST['new-cap'] ) ) {
40
+
41
+ /* Loop through each new capability from the edit roles form. */
42
+ foreach ( $_POST['new-cap'] as $new_cap ) {
43
+
44
+ /* Sanitize the new capability to remove any unwanted characters. */
45
+ $new_cap = strip_tags( $new_cap );
46
+ $new_cap = str_replace( array( '-', ' ', '&nbsp;' ) , '_', $new_cap );
47
+ $new_cap = preg_replace('/[^A-Za-z0-9_]/', '', $new_cap );
48
+ $new_cap = strtolower( $new_cap );
49
+
50
+ /* Run one more check to make sure the new capability exists. Add the cap to the role. */
51
+ if ( $new_cap && !$role->has_cap( $new_cap ) )
52
+ $role->add_cap( $new_cap );
53
+
54
+ } // End loop through new capabilities
55
+
56
+ } // End check for new capabilities
57
+
58
+ } // End check for form submission ?>
59
+
60
+ <div class="wrap">
61
+
62
+ <h2><?php printf(__('Edit the %1$s role', 'members'), $role->name ); ?></h2>
63
+
64
+ <?php if ( $role_updated ) members_admin_message( '', __('Role updated.', 'members') ); ?>
65
+
66
+ <?php do_action( 'members_pre_edit_role_form' ); //Available pre-form hook for displaying messages. ?>
67
+
68
+ <div id="poststuff">
69
+
70
+ <form name="form0" method="post" action="<?php echo admin_url( esc_url( "users.php?page=roles&amp;action=edit&amp;role={$role->name}" ) ); ?>" style="border:none;background:transparent;">
71
+
72
+ <?php wp_nonce_field( members_get_nonce( 'edit-roles' ) ); ?>
73
+
74
+ <div class="postbox open">
75
+
76
+ <h3><?php printf( __('<strong>Role:</strong> %1$s', 'members'), $role->name ); ?></h3>
77
+
78
+ <div class="inside">
79
+
80
+ <table class="form-table">
81
+
82
+ <tr>
83
+ <th style="width: 20%;">
84
+ <strong><?php _e('Capabilities', 'members'); ?></strong>
85
+ </th>
86
+
87
+ <td>
88
+ <?php _e('Select which capabilities this role should have. Make sure you understand what the capability does before giving it to just any role. This is a powerful feature, but it can cause you some grief if you give regular ol\' Joe more capabilities than yourself.', 'members'); ?>
89
+ <br /><br />
90
+ <?php
91
+
92
+ /* Looop through each available capability. */
93
+ foreach ( members_get_capabilities() as $cap ) {
94
+
95
+ /* If the role has the capability, set the checkbox to 'checked'. */
96
+ if ( $role->has_cap( $cap ) )
97
+ $checked = " checked='checked' ";
98
+
99
+ /* If the role doesn't have the the capability, set the checkbox value to false. */
100
+ else
101
+ $checked = ''; ?>
102
+
103
+ <div style='overflow: hidden; margin: 0 0 5px 0; float:left; width: 32.67%;'>
104
+ <input name='<?php echo "role-caps[{$role->name}-{$cap}]"; ?>' id='<?php echo "{$role->name}-{$cap}"; ?>' <?php echo $checked; ?> type='checkbox' value='true' />
105
+ <label for="<?php echo "{$role->name}-{$cap}"; ?>"><?php if ( $checked ) echo "<strong>$cap</strong>"; else echo "<em>$cap</em>"; ?></label>
106
+ </div>
107
+
108
+ <?php } // Endforeach ?>
109
+ </td>
110
+ </tr>
111
+
112
+ <tr>
113
+ <th style="width: 20%;">
114
+ <strong><?php _e('New Capabilities', 'members'); ?></strong>
115
+ </th>
116
+
117
+ <td>
118
+ <?php _e('Add up to six new capabilities with this form for this role (more can be added later). Please only use letters, numbers, and underscores.', 'members'); ?>
119
+ <br /><br />
120
+ <p style="margin: 0 0 5px 0; float:left; width: 32.67%;">
121
+ <input id="new-cap-1" name="new-cap[]" value="" size="20" />
122
+ </p>
123
+ <p style="margin: 0 0 5px 0; float:left; width: 32.67%;">
124
+ <input id="new-cap-2" name="new-cap[]" value="" size="20" />
125
+ </p>
126
+ <p style="margin: 0 0 5px 0; float:left; width: 32.67%;">
127
+ <input id="new-cap-3" name="new-cap[]" value="" size="20" />
128
+ </p>
129
+ <p style="margin: 0 0 5px 0; float:left; width: 32.67%;">
130
+ <input id="new-cap-4" name="new-cap[]" value="" size="20" />
131
+ </p>
132
+ <p style="margin: 0 0 5px 0; float:left; width: 32.67%;">
133
+ <input id="new-cap-5" name="new-cap[]" value="" size="20" />
134
+ </p>
135
+ <p style="margin: 0 0 5px 0; float:left; width: 32.67%;">
136
+ <input id="new-cap-6" name="new-cap[]" value="" size="20" />
137
+ </p>
138
+
139
+ </td>
140
+ </tr>
141
+
142
+ </table><!-- .form-table -->
143
+
144
+ </div><!-- .inside -->
145
+
146
+ </div><!-- .postbox .open -->
147
+
148
+ <p class="submit" style="clear:both;">
149
+ <input type="submit" name="Submit" class="button-primary" value="<?php _e('Save Changes', 'cleaner_gallery') ?>" />
150
+ <input type="hidden" name="edit-role-saved" value="Y" />
151
+ </p><!-- .submit -->
152
+
153
+ </form>
154
+
155
+ </div><!-- #poststuff -->
156
+
157
+ </div><!-- .wrap -->
components/edit-roles/edit-roles.php ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Edit Roles page displays all of the site's roles in an easy-to-read manner. Along with
4
+ * each role, the number of users and capabilities are displayed. Roles without users are
5
+ * considered "inactive" roles within this plugin's system.
6
+ *
7
+ * All roles can be edited. However, the current user's role and the default role cannot be
8
+ * deleted. To delete the current user's role, another logged-in user with the 'delete_roles'
9
+ * capability and a different role must perform this action. To delete the default role, the
10
+ * default must be changed under the General Options page in the WordPress admin.
11
+ *
12
+ * Users of roles that are deleted will be given the default role (typically 'Subscriber'). It
13
+ * is advisable to not make such a change with a large number of users because a new user
14
+ * object must be created to change each individual user.
15
+ *
16
+ * @todo Test deleting a role with 100s (even 1,000s) of users to see what sort of strain this has.
17
+ *
18
+ * @package Members
19
+ * @subpackage Components
20
+ */
21
+
22
+ /* Get the global $members variable. */
23
+ global $members;
24
+
25
+ /* Current user in the admin. */
26
+ $user = new WP_User( $members->current_user->ID );
27
+
28
+ /* Set the available roles array.*/
29
+ $avail_roles = array();
30
+
31
+ /* Get all the users of the current blog. */
32
+ $users_of_blog = get_users_of_blog();
33
+
34
+ /* Loop through each user. */
35
+ foreach ( (array)$users_of_blog as $blog_user ) {
36
+
37
+ $meta_values = unserialize( $blog_user->meta_value );
38
+
39
+ foreach ( ( array) $meta_values as $role => $value ) {
40
+
41
+ if ( !isset( $avail_roles[$role] ) )
42
+ $avail_roles[$role] = 0;
43
+
44
+ ++$avail_roles[$role];
45
+ }
46
+ }
47
+
48
+ /* Destroy the $users_of_blog variable. */
49
+ unset( $users_of_blog );
50
+
51
+ /* Can the current user delete_roles? */
52
+ if ( current_user_can( 'delete_roles' ) )
53
+ $delete_roles = true;
54
+
55
+ /* Get the default role. */
56
+ $default_role = get_option( 'default_role' );
57
+
58
+ /* Sort out the roles, active roles, and inactive roles. */
59
+ $all_roles = $active_roles = $inactive_roles = 0;
60
+
61
+ /* Loop through all of the roles, adding each role to its respective category (active, inactive). */
62
+ foreach ( $wp_roles->role_names as $role => $name ) {
63
+ $all_roles++;
64
+ if ( $avail_roles[$role] ) {
65
+ $active_roles++;
66
+ $active_roles_arr[$role] = $name;
67
+ }
68
+ else {
69
+ $inactive_roles++;
70
+ $inactive_roles_arr[$role] = $name;
71
+ }
72
+ }
73
+
74
+ /* Set variables for when role_status is active. */
75
+ if ( 'active' == $_GET['role_status'] ) {
76
+ $roles_loop_array = $active_roles_arr;
77
+ $title = __('Edit Active Roles', 'members');
78
+ $current_page = admin_url( esc_url( "users.php?page=roles&role_status=active" ) );
79
+ }
80
+
81
+ /* Set variables for when role_status is inactive. */
82
+ elseif ( 'inactive' == $_GET['role_status'] ) {
83
+ $roles_loop_array = $inactive_roles_arr;
84
+ $title = __('Edit Inactive Roles', 'members');
85
+ $current_page = admin_url( esc_url( "users.php?page=roles&role_status=inactive" ) );
86
+ }
87
+
88
+ /* Set default variables for when role_status is neither active nor inactive. */
89
+ else {
90
+ $roles_loop_array = $wp_roles->role_names;
91
+ $title = __('Edit Roles', 'members');
92
+ $current_page = admin_url( esc_url( "users.php?page=roles" ) );
93
+ }
94
+
95
+ /* Sort the roles array into alphabetical order. */
96
+ ksort( $roles_loop_array ); ?>
97
+
98
+ <div class="wrap">
99
+
100
+ <h2><?php echo $title; ?></h2>
101
+
102
+ <?php do_action( 'members_pre_edit_roles_form' ); // Available action hook for displaying messages. ?>
103
+
104
+ <div id="poststuff">
105
+
106
+ <form id="roles" action="<?php echo $current_page; ?>" method="post">
107
+
108
+ <?php wp_nonce_field( members_get_nonce( 'edit-roles' ) ); ?>
109
+
110
+ <ul class="subsubsub">
111
+ <li><a <?php if ( 'active' !== $_GET['role_status'] && 'inactive' !== $_GET['role_status'] ) echo 'class="current"'; ?> href="<?php echo admin_url( esc_url( "users.php?page=roles" ) ); ?>">All <span class="count">(<span id="all_count"><?php echo $all_roles; ?></span>)</span></a> | </li>
112
+ <li><a <?php if ( 'active' == $_GET['role_status'] ) echo 'class="current"'; ?> href="<?php echo admin_url( esc_url( "users.php?page=roles&amp;role_status=active" ) ); ?>">Active <span class="count">(<span id="active_count"><?php echo $active_roles; ?></span>)</span></a> | </li>
113
+ <li><a <?php if ( 'inactive' == $_GET['role_status'] ) echo 'class="current"'; ?> href="<?php echo admin_url( esc_url( "users.php?page=roles&amp;role_status=inactive" ) ); ?>">Inactive <span class="count">(<span id="inactive_count"><?php echo $inactive_roles; ?></span>)</span></a></li>
114
+ </ul><!-- .subsubsub -->
115
+
116
+ <div class="tablenav">
117
+
118
+ <div class="alignleft actions">
119
+ <select name="action">
120
+ <option value="" selected="selected">Bulk Actions</option>
121
+ <?php if ( $delete_roles ) echo '<option value="delete">Delete</option>'; ?>
122
+ </select>
123
+ <input type="submit" value="<?php _e('Apply', 'members'); ?>" name="doaction" id="doaction" class="button-secondary action" />
124
+ </div><!-- .alignleft .actions -->
125
+
126
+ <br class="clear" />
127
+
128
+ </div><!-- .tablenav -->
129
+
130
+ <table class="widefat fixed" cellspacing="0">
131
+ <thead>
132
+ <tr>
133
+ <th class='check-column'><input type='checkbox' /></th>
134
+ <th class='name-column'><?php _e('Role Name', 'members'); ?></th>
135
+ <th><?php _e('Role', 'members'); ?></th>
136
+ <th><?php _e('Users', 'members'); ?></th>
137
+ <th><?php _e('Capabilities', 'members'); ?></th>
138
+ </tr>
139
+ </thead>
140
+
141
+ <tfoot>
142
+ <tr>
143
+ <th class='check-column'><input type='checkbox' /></th>
144
+ <th class='name-column'><?php _e('Role Name', 'members'); ?></th>
145
+ <th><?php _e('Role', 'members'); ?></th>
146
+ <th><?php _e('Users', 'members'); ?></th>
147
+ <th><?php _e('Capabilities', 'members'); ?></th>
148
+ </tr>
149
+ </tfoot>
150
+
151
+ <tbody id="users" class="list:user user-list plugins">
152
+
153
+ <?php foreach ( $roles_loop_array as $role => $name ) { ?>
154
+
155
+ <?php $name = str_replace( '|User role', '', $name ); ?>
156
+
157
+ <tr valign="top" class="<?php if ( $avail_roles[$role] ) echo 'active'; else echo 'inactive'; ?>">
158
+
159
+ <th class="manage-column column-cb check-column">
160
+ <?php if ( $role !== $default_role && !$user->has_cap( $role ) ) { ?>
161
+ <input name="roles[<?php echo $role; ?>]" id="<?php echo $role; ?>" type="checkbox" value="<?php echo $role; ?>" />
162
+ <?php } ?>
163
+ </th><!-- .manage-column .column-cb .check-column -->
164
+
165
+ <td class='plugin-title'>
166
+ <?php $edit_link = admin_url( wp_nonce_url( "users.php?page=roles&amp;action=edit&amp;role={$role}", members_get_nonce( 'edit-roles' ) ) ); ?>
167
+
168
+ <a href="<?php echo $edit_link; ?>" title="<?php printf( __('Edit the %1$s role', 'members'), $name ); ?>"><strong><?php echo $name; ?></strong></a>
169
+
170
+ <div class="row-actions">
171
+ <a href="<?php echo $edit_link; ?>" title="<?php printf( __('Edit the %1$s role', 'members'), $name ); ?>"><? _e('Edit', 'members'); ?></a>
172
+
173
+ <?php /* Delete role link. */
174
+ if ( $delete_roles && $role !== $default_role && !$user->has_cap( $role ) ) {
175
+ $delete_link = admin_url( wp_nonce_url( "users.php?page=roles&amp;action=delete&amp;role={$role}", members_get_nonce( 'edit-roles' ) ) ); ?>
176
+ | <a href="<?php echo $delete_link; ?>" title="<?php printf( __('Delete the %1$s role', 'members'), $name ); ?>">Delete</a>
177
+ <?php }
178
+
179
+ /* Link to change the default role Options General. */
180
+ if ( $role == $default_role ) { ?>
181
+ | <a href="<?php echo admin_url( ( 'options-general.php' ) ); ?>" title="<?php _e('Change default role', 'members'); ?>"><?php _e('Default Role', 'members'); ?></a>
182
+ <?php }
183
+
184
+ /* If there are users, provide a link to the users page of that role. */
185
+ if ( $avail_roles[$role] ) { ?>
186
+ | <a href="<?php echo admin_url( esc_url( "users.php?role={$role}" ) ); ?>" title="<?php printf( __('View all users with the %1$s role', 'members'), $name ); ?>"><?php _e('View Users', 'members'); ?></a>
187
+ <?php } ?>
188
+
189
+ </div><!-- .row-actions -->
190
+
191
+ </td><!-- .plugin-title -->
192
+
193
+ <td class='desc'>
194
+ <p><?php echo $role; ?></p>
195
+ </td><!-- .desc -->
196
+
197
+ <td class='desc'>
198
+ <p><?php /* Check if any users are assigned to the role. If so, display a link to the role's users page. */
199
+ if ( 1 < $avail_roles[$role] )
200
+ echo '<a href="' . admin_url( esc_url( "users.php?role={$role}" ) ) . '" title="' . sprintf( __('View all users with the %1$s role', 'members'), $name ) . '">' . sprintf( __('%1$s Users', 'members'), $avail_roles[$role] ) . '</a>';
201
+ elseif ( 1 == $avail_roles[$role] )
202
+ echo '<a href="' . admin_url( esc_url( "users.php?role={$role}" ) ) . '" title="' . sprintf( __('View all users with the %1$s role', 'members'), $name ) . '">' . __('1 User', 'members') . '</a>';
203
+ else
204
+ echo '<em>' . __('No users have this role.', 'members') . '</em>';
205
+ ?></p>
206
+ </td><!-- .desc -->
207
+
208
+ <td class='desc'>
209
+ <p>
210
+ <?php /* Check if the role has any capabilities. */
211
+
212
+ $role_2 = get_role( $role );
213
+
214
+ if ( is_array( $role_2->capabilities ) ) {
215
+ $cap_count = count( $role_2->capabilities );
216
+ if ( 1 < $cap_count ) printf( __('%1$s Capabilities', 'members'), $cap_count );
217
+ elseif ( 1 == $cap_count ) _e('1 Capability', 'members');
218
+ }
219
+ else
220
+ echo '<em>' . __('This role has no capabilities', 'members') . '</em>'; ?>
221
+ </p>
222
+ </td><!-- .desc -->
223
+
224
+ </tr><!-- .active .inactive -->
225
+
226
+ <?php } // End foreach ?>
227
+
228
+ </tbody><!-- #users .list:user .user-list .plugins -->
229
+
230
+ </table><!-- .widefat .fixed -->
231
+
232
+ <div class="tablenav">
233
+
234
+ <div class="alignleft actions">
235
+ <select name="action2">
236
+ <option value="" selected="selected">Bulk Actions</option>
237
+ <?php if ( $delete_roles ) echo '<option value="delete">Delete</option>'; ?>
238
+ </select>
239
+ <input type="submit" value="Apply" name="doaction2" id="doaction2" class="button-secondary action" />
240
+ </div><!-- .alignleft .actions -->
241
+
242
+ <br class="clear" />
243
+
244
+ </div><!-- .tablenav -->
245
+
246
+ </form><!-- #roles -->
247
+
248
+ </div><!-- #poststuff -->
249
+
250
+ </div><!-- .wrap -->
components/edit-roles/manage-roles.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The main file of the Edit Roles component. This is where we run checks to see which page
4
+ * needs to be loaded. It also checks if actions have been performed on the Edit Roles page.
5
+ *
6
+ * @package Members
7
+ * @subpackage Components
8
+ */
9
+
10
+ /* Get the $wp_roles variable and $wpdb. Do we need $wpdb (need to check)? */
11
+ global $wp_roles, $wpdb;
12
+
13
+ /* Get the current action performed by the user. */
14
+ $action = $_GET['action'];
15
+
16
+ /* If a role has been updated, set the action to 'role-updated'. */
17
+ if ( $_POST[$hidden_field_name] == 'Y' )
18
+ $action = 'role-updated';
19
+
20
+ /* If the bulk delete (first submit) has been selected. */
21
+ elseif ( 'delete' == $_POST['action'] && __('Apply', 'members') == $_POST['doaction'] )
22
+ $action = 'bulk-delete';
23
+
24
+ /* If the bulk delete (second submit) has been selected. */
25
+ elseif ( 'delete' == $_POST['action2'] && __('Apply', 'members') == $_POST['doaction2'] )
26
+ $action = 'bulk-delete';
27
+
28
+ /* Choose which actions to perform and pages to load according to the $action variable. */
29
+ switch( $action ) {
30
+
31
+ /* If the bulk delete was selected. */
32
+ case 'bulk-delete' :
33
+
34
+ /* Get the default role (we don't want to delete this). */
35
+ $default_role = get_option( 'default_role' );
36
+
37
+ /* Get all roles checked for deletion. */
38
+ $delete_roles = $_POST['roles'];
39
+
40
+ /* If no roles were selected, break. Just load up the edit roles page. */
41
+ if ( !is_array( $delete_roles ) ) {
42
+ require_once( 'edit-roles.php' );
43
+ break;
44
+ }
45
+
46
+ /* If roles were selected, let's delete some roles. */
47
+ else {
48
+
49
+ /* Verify the nonce. */
50
+ check_admin_referer( members_get_nonce( 'edit-roles' ) );
51
+
52
+ /* Send through roles deleted message. */
53
+ add_action( 'members_pre_edit_roles_form', 'members_message_roles_deleted' );
54
+
55
+ /* Loop through each of the selected roles. */
56
+ foreach ( $delete_roles as $role ) {
57
+
58
+ /* Get all users with the current role of the loop. */
59
+ $wp_user_search = new WP_User_Search( '', '', $role );
60
+ $change_users = $wp_user_search->get_results();
61
+
62
+ /* If there are users with the role, let's delete them and give them the default role. */
63
+ if ( isset( $change_users ) && is_array( $change_users ) ) {
64
+
65
+ /* Loop through each of the users we need to change. */
66
+ foreach( $change_users as $move_user ) {
67
+ $new_user = new WP_User( $move_user );
68
+
69
+ /* If the user has the role, remove it and set the default role. Do we need this additional check? */
70
+ if ( $new_user->has_cap( $role ) ) {
71
+ $new_user->remove_role( $role );
72
+ $new_user->set_role( $default_role );
73
+ }
74
+ }
75
+ }
76
+
77
+ /* Remove the role. */
78
+ remove_role( $role );
79
+ }
80
+
81
+ /* Load the edit roles page. */
82
+ require_once( 'edit-roles.php' );
83
+ break;
84
+ }
85
+ break;
86
+
87
+ /* If a single role has been chosen to be deleted. */
88
+ case 'delete' :
89
+
90
+ /* Verify the referer. */
91
+ check_admin_referer( members_get_nonce( 'edit-roles' ) );
92
+
93
+ /* Send role deleted message. */
94
+ add_action( 'members_pre_edit_roles_form', 'members_message_role_deleted' );
95
+
96
+ /* Get the default role. */
97
+ $default_role = get_option( 'default_role' );
98
+
99
+ /* Get the role we want to delete. */
100
+ $role = $_GET['role'];
101
+
102
+ /* Get all users with the role to be deleted. */
103
+ $wp_user_search = new WP_User_Search( '', '', $role );
104
+ $change_users = $wp_user_search->get_results();
105
+
106
+ /* If there are users with the role we're deleting, loop through them, remove the role, and set the default role. */
107
+ if ( isset( $change_users ) && is_array( $change_users ) ) {
108
+ foreach( $change_users as $move_user ) {
109
+ $new_user = new WP_User( $move_user );
110
+
111
+ /* If the user has the role, remove it and set the default. Do we need this check? */
112
+ if ( $new_user->has_cap( $role ) ) {
113
+ $new_user->remove_role( $role );
114
+ $new_user->set_role( $default_role );
115
+ }
116
+ }
117
+ }
118
+
119
+ /* Remove the role. */
120
+ remove_role( $role );
121
+
122
+ /* Load the edit roles page. */
123
+ require_once( 'edit-roles.php' );
124
+ break;
125
+
126
+ /* If a role has been updated. Is this needed still? */
127
+ case 'role-updated' :
128
+
129
+ /* Set some default variables. */
130
+ $title = __('Edit Role', 'members');
131
+ $role = $_GET['role'];
132
+
133
+ /* Load the edit role form. */
134
+ require_once('edit-role-form.php');
135
+ break;
136
+
137
+ /* If a role has been selected to be edited. */
138
+ case 'edit' :
139
+
140
+ /* Verify the referer. */
141
+ check_admin_referer( members_get_nonce( 'edit-roles' ) );
142
+
143
+ /* Set some default variables. */
144
+ $title = __('Edit Role', 'members');
145
+ $role = $_GET['role'];
146
+
147
+ /* Load the edit role form. */
148
+ require_once('edit-role-form.php');
149
+
150
+ break;
151
+
152
+ /* The default page is the edit roles page. */
153
+ default :
154
+
155
+ /* Load the edit roles page.*/
156
+ require_once( 'edit-roles.php' );
157
+ break;
158
+ }
159
+
160
+ ?>
components/new-roles/default.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The New Roles component allows users with the 'create_roles' capability to
4
+ * create new roles for use on the site.
5
+ *
6
+ * @package Members
7
+ * @subpackage Components
8
+ */
9
+
10
+ /* Add message when no role has the 'create_roles' capability. */
11
+ add_action( 'members_pre_components_form', 'members_message_no_create_roles' );
12
+ add_action( 'members_pre_new_role_form', 'members_message_no_create_roles' );
13
+
14
+ /**
15
+ * Returns an array of capabilities that should be set on the New Role admin screen.
16
+ * By default, the only capability checked is 'read' because it's fairly common.
17
+ *
18
+ * @since 0.1
19
+ * @return $capabilities array Default capabilities for new roles.
20
+ */
21
+ function members_new_role_default_capabilities() {
22
+
23
+ $capabilities = array( 'read' );
24
+
25
+ /* Filters should return an array. */
26
+ return apply_filters( 'members_new_role_default_capabilities', $capabilities );
27
+ }
28
+
29
+ /**
30
+ * Displays a message if the New Roles component is active and no
31
+ * roles have the 'create_roles' capability.
32
+ *
33
+ * @since 0.1
34
+ */
35
+ function members_message_no_create_roles() {
36
+ if ( is_active_members_component( 'new_roles' ) && !members_check_for_cap( 'create_roles' ) ) {
37
+ $message = __('To create new roles, you must give the <code>create_roles</code> capability to at least one role.', 'members');
38
+ members_admin_message( '', $message );
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Loads the settings pages for the New Roles component. For a logged-in
44
+ * user to see this additional page, they must have the 'create_roles' capability.
45
+ * In order to gain this capability, one should use the Edit Roles component to give
46
+ * a role or multiple roles this capability.
47
+ *
48
+ * @since 0.1
49
+ * @uses add_submenu_page() Adds a submenu to the users menu.
50
+ */
51
+ function members_component_load_new_roles() {
52
+ global $members_new_role_page;
53
+
54
+ /* Create the New Role page. */
55
+ $members_new_roles_page = add_submenu_page( 'users.php', __('New Role', 'members'), __('New Role', 'members'), 'create_roles', 'new-role', 'members_new_role_page' );
56
+ }
57
+
58
+ /**
59
+ * Loads the New Role page when its needed.
60
+ *
61
+ * @since 0.1
62
+ */
63
+ function members_new_role_page() {
64
+ require_once( MEMBERS_COMPONENTS . '/new-roles/new-role.php' );
65
+ }
66
+
67
+ ?>
components/new-roles/new-role.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Page for creating new roles. Displays the new role form and creates
4
+ * a new role if a new role has been submitted.
5
+ *
6
+ * @package Members
7
+ * @subpackage Components
8
+ */
9
+
10
+ /* Check if the form has been submitted. */
11
+ if ( $_POST['new-role-submit'] == 'Y' ) {
12
+
13
+ /* Verify the nonce. */
14
+ check_admin_referer( members_get_nonce( 'new-role' ) );
15
+
16
+ /* Check if any capabilities were selected. */
17
+ if ( !empty( $_POST['capabilities'] ) && is_array( $_POST['capabilities'] ) )
18
+ $new_user_caps = $_POST['capabilities'];
19
+
20
+ /* If no capabilities were selected, set the variable to null. */
21
+ else
22
+ $new_user_caps = null;
23
+
24
+ /* Check if both a role name and role were submitted. */
25
+ if ( $_POST['role-name'] && $_POST['role-id'] ) {
26
+
27
+ /* Sanitize the new role, removing any unwanted characters. */
28
+ $new_role = strip_tags( $_POST['role-id'] );
29
+ $new_role = str_replace( array( '-', ' ', '&nbsp;' ) , '_', $new_role );
30
+ $new_role = preg_replace('/[^A-Za-z0-9_]/', '', $new_role );
31
+ $new_role = strtolower( $new_role );
32
+
33
+ /* Sanitize the new role name/label. We just want to strip any tags here. */
34
+ $new_role_name = strip_tags( $_POST['role-name'] ); // Should we use something like the WP user sanitation method?
35
+
36
+ /* Add a new role with the data input. */
37
+ $new_role_added = add_role( $new_role, $new_role_name, $new_user_caps );
38
+
39
+ } // End check for role and role name
40
+
41
+ } // End check for form submit ?>
42
+
43
+ <div class="wrap">
44
+
45
+ <h2><?php _e('Add a new user role', 'members'); ?></h2>
46
+
47
+ <?php if ( $new_role_added ) members_admin_message( '', sprintf( __('The %1$s role has been created.', 'members'), $_POST['role-name'] ) ); ?>
48
+
49
+ <?php do_action( 'members_pre_new_role_form' ); // Available action hook for displaying messages. ?>
50
+
51
+ <div id="poststuff">
52
+
53
+ <form name="form0" method="post" action="<?php echo admin_url( "users.php?page=new-role" ); ?>" style="border:none;background:transparent;">
54
+
55
+ <?php wp_nonce_field( members_get_nonce( 'new-role' ) ); ?>
56
+
57
+ <div class="postbox open">
58
+
59
+ <h3><?php _e('Create a new user role', 'members'); ?></h3>
60
+
61
+ <div class="inside">
62
+
63
+ <table class="form-table">
64
+ <tr>
65
+ <th style="width: 20%;">
66
+ <strong><?php _e('About:', 'members'); ?></strong>
67
+ </th>
68
+ <td>
69
+ <?php printf( __('Here you can create as many new roles as you\'d like. Roles are a way of grouping your users. You can give individual users a role from the <a href="%1$s" title="Manage Users">user management</a> screen. This will allow you to do specific things for users with a specific role. Once you\'ve created a new role, you can manage it with the <em>Edit Roles</em> component.', 'members'), admin_url( 'users.php' ) ); ?>
70
+ </td>
71
+ </tr>
72
+
73
+ <tr>
74
+ <th style="width: 20%;">
75
+ <label for="role-id"><strong><?php _e('Role:', 'members'); ?></strong></label>
76
+ </th>
77
+ <td>
78
+ <?php _e('<strong>Required:</strong> Enter the name of your role. This is a unique key that should only contain numbers, letters, and underscores. Please don\'t add spaces or other odd characters.', 'members'); ?>
79
+ <br />
80
+ <input id="role-id" name="role-id" value="" size="30" />
81
+ </td>
82
+ </tr>
83
+
84
+ <tr>
85
+ <th style="width: 20%;">
86
+ <label for="role-name"><strong><?php _e('Role Label:', 'members'); ?></strong></label>
87
+ </th>
88
+ <td>
89
+ <?php _e('<strong>Required:</strong> Enter a label your role. This will be the title that is displayed in most cases.', 'members'); ?>
90
+ <br />
91
+ <input id="role-name" name="role-name" value="" size="30" />
92
+ </td>
93
+ </tr>
94
+
95
+ <tr>
96
+ <th style="width: 20%;">
97
+ <strong><?php _e('Capabilities:', 'members'); ?></strong>
98
+ </th>
99
+ <td>
100
+ <?php _e('<strong>Optional:</strong> Select which capabilities your new role should have. These may be changed later using the <em>Edit Roles</em> component.', 'members'); ?>
101
+ <br /><br />
102
+ <?php foreach ( members_get_capabilities() as $cap ) : ?>
103
+ <div style="float: left; width: 32.67%; margin: 0 0 5px 0;">
104
+ <input name='capabilities[<?php echo $cap; ?>]' id='capabilities-<?php echo $cap; ?>' type="checkbox" value='<?php echo $cap; ?>' <?php if ( in_array( $cap, members_new_role_default_capabilities() ) ) echo "checked='checked'"; ?> />
105
+ <label for="capabilities-<?php echo $cap; ?>"><?php if ( in_array( $cap, members_new_role_default_capabilities() ) ) echo "<strong>$cap</strong>"; else echo $cap; ?></label>
106
+ </div>
107
+ <?php endforeach; ?>
108
+ </td>
109
+ </tr>
110
+
111
+ </table><!-- .form-table -->
112
+
113
+ </div><!-- .inside -->
114
+
115
+ </div><!-- .postbox -->
116
+
117
+ <p class="submit">
118
+ <input type="submit" name="Submit" class="button-primary" value="<?php _e('Create Role', 'members') ?>" />
119
+ <input type="hidden" name="new-role-submit" value="Y" />
120
+ </p><!-- .submit -->
121
+
122
+ </form>
123
+
124
+ </div><!-- #poststuff -->
125
+
126
+ </div><!-- .poststuff -->
components/private-blog/default.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Private Blog component is for making your site completely private to people that are
4
+ * not logged into the site. If not logged in, it will redirect all people to the 'wp-login.php' page.
5
+ *
6
+ * @todo Make sure 'blog_public' is set to true.
7
+ * @todo Disable content from feeds or add an additional feed component.
8
+ *
9
+ * @package Members
10
+ * @subpackage Components
11
+ */
12
+
13
+ /* Redirects users to the login page. */
14
+ add_action( 'template_redirect', 'members_please_log_in' );
15
+
16
+ /**
17
+ * Redirects users that are not logged in to the 'wp-login.php' page.
18
+ *
19
+ * @since 0.1
20
+ * @uses is_user_logged_in() Checks if the current user is logged in.
21
+ * @uses auth_redirect() Redirects people that are not logged in to the login page.
22
+ */
23
+ function members_please_log_in() {
24
+ if ( !is_user_logged_in() && !strpos( $_SERVER['SCRIPT_NAME'], 'wp-login.php' ) )
25
+ auth_redirect();
26
+ }
27
+
28
+ ?>
components/shortcodes/shortcodes.php ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Shortcodes component provides additional [shortcodes] for use within posts/pages
4
+ * and any other shortcode-capable area.
5
+ *
6
+ * @todo need a [hide] shortcode or allow [access] to do the opposite.
7
+ *
8
+ * @package Members
9
+ * @subpackage Components
10
+ */
11
+
12
+ /* Add shortcodes. */
13
+ add_shortcode( 'login-form', 'members_login_form_shortcode' );
14
+ add_shortcode( 'access', 'members_access_check_shortcode' );
15
+ add_shortcode( 'feed', 'members_access_check_shortcode' );
16
+ add_shortcode( 'is_user_logged_in', 'members_is_user_logged_in_shortcode' );
17
+ add_shortcode( 'get_avatar', 'members_get_avatar_shortcode' );
18
+ add_shortcode( 'avatar', 'members_get_avatar_shortcode' );
19
+
20
+ /**
21
+ * Displays an avatar for any user. At the very least, an ID or email must
22
+ * be input. Otherwise, we can't know which avatar to grab.
23
+ *
24
+ * Users should input the code as [get_avatar id="30" alt="Justin Tadlock"].
25
+ *
26
+ * @since 0.1
27
+ * @uses get_avatar() Grabs the users avatar.
28
+ * @param $attr array The shortcode attributes.
29
+ */
30
+ function members_get_avatar_shortcode( $attr ) {
31
+
32
+ /* Set up our default attributes. */
33
+ $defaults = array(
34
+ 'id' => '',
35
+ 'email' => '',
36
+ 'size' => 96,
37
+ 'default' => '',
38
+ 'alt' => ''
39
+ );
40
+
41
+ /* Merge the input attributes and the defaults. */
42
+ extract( shortcode_atts( $defaults, $attr ) );
43
+
44
+ /* If an email was input, use it. */
45
+ if ( $email )
46
+ $id_or_email = $email;
47
+
48
+ /* If no email was input, use the ID. */
49
+ else
50
+ $id_or_email = $id;
51
+
52
+ /* Return the avatar. */
53
+ return get_avatar( $id_or_email, $size, $default, $alt );
54
+ }
55
+
56
+ /**
57
+ * Displays content if the user viewing it is currently logged in. This also blocks
58
+ * content from showing in feeds.
59
+ *
60
+ * Content needs to be wrapped with this shortcode like
61
+ * [is_user_logged_in]This is content.[/is_user_logged_in].
62
+ *
63
+ * @todo Provide a filter hook for displaying a "please log in to view" message.
64
+ *
65
+ * @since 0.1
66
+ * @uses is_feed() Checks if the content is currently being shown in a feed.
67
+ * @uses is_user_logged_in() Checks if the current user is logged in.
68
+ * @param $attr array Attributes for the shortcode (not usefule here).
69
+ * @param $content string The content located between the opening and closing of the shortcode.
70
+ * @return $content string The content to be shown.
71
+ */
72
+ function members_is_user_logged_in_shortcode( $attr, $content = null ) {
73
+
74
+ /* If it is a feed or the user is not logged in, return nothing. */
75
+ if ( !is_feed() || !is_user_logged_in() )
76
+ return '';
77
+
78
+ /* Return the content. */
79
+ return $content;
80
+ }
81
+
82
+ /**
83
+ * Content that should only be shown in feed readers. Can be useful for
84
+ * displaying feed-specific items.
85
+ *
86
+ * Content should be wrapped like [feed]This is content.[/feed].
87
+ *
88
+ * @since 0.1
89
+ * @uses is_feed() Checks if the content is currently being shown in a feed.
90
+ * @uses is_null() Checks if there is any content.
91
+ * @param $attr array Attributes for the shortcode (not currently useful but may later add a $display/$show parameter).
92
+ * @param $content string The content located between the opening and closing of the shortcode.
93
+ * @return $content string The content to be shown.
94
+ */
95
+ function members_feed_shortcode( $attr, $content = null ) {
96
+
97
+ /* If not feed or no content exists, return nothing. */
98
+ if ( !is_feed() || is_null( $content ) )
99
+ return '';
100
+
101
+ /* Return the content. */
102
+ return $content;
103
+ }
104
+
105
+ /**
106
+ * Provide/restrict access to specific roles or capabilities. This content should
107
+ * not be shown in feeds.
108
+ *
109
+ * @todo Allow multiple roles and capabilities to be input (comma-separated).
110
+ *
111
+ * Content should be wrapped like [access role="editor"]This is content.[/access].
112
+ *
113
+ * @since 0.1
114
+ * @uses current_user_can() Checks if the current user has the role or capability.
115
+ * @uses is_feed() Checks if we're currently viewing a feed.
116
+ * @param $attr array The shortcode attributes.
117
+ * @param $content string The content that should be shown/restricted.
118
+ * @return $content string The content if it should be shown. Else, return nothing.
119
+ */
120
+ function members_access_check_shortcode( $attr, $content = null ) {
121
+
122
+ /* Set up the default attributes. */
123
+ $defaults = array(
124
+ 'capability' => '',
125
+ 'role' => '',
126
+ 'feed' => false,
127
+ );
128
+
129
+ /* Merge the input attributes and the defaults. */
130
+ extract( shortcode_atts( $defaults, $attr ) );
131
+
132
+ /* If the current user has the input capability, show the content. */
133
+ if ( $capability && current_user_can( $capability ) )
134
+ return $content;
135
+
136
+ /* If the current user has the input role, show the content. */
137
+ elseif ( $role && current_user_can( $role ) )
138
+ return $content;
139
+
140
+ /* If $feed was set to true and we're currently displaying a feed, show the content. */
141
+ elseif ( $feed && 'false' !== $feed && is_feed() )
142
+ return $content;
143
+
144
+ /* If there is no content, return nothing. */
145
+ elseif ( !is_null( $content ) )
146
+ return '';
147
+
148
+ /* Return nothing if none of the conditions have been met. */
149
+ return '';
150
+ }
151
+
152
+ /**
153
+ * Displays a login form.
154
+ *
155
+ * @since 0.1
156
+ * @uses members_get_login_form() Displays the login form.
157
+ */
158
+ function members_login_form_shortcode() {
159
+
160
+ return members_get_login_form();
161
+ }
162
+
163
+ ?>
components/template-tags/template-tags.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Template Tags component is for adding functions that could be useful within the
4
+ * template files of a WordPress theme.
5
+ *
6
+ * @todo Add members_count_users( $role = '' )
7
+ *
8
+ * @package Members
9
+ * @subpackage Components
10
+ */
11
+
12
+ /**
13
+ * Use to put an author box at the end/beginning of a post. This template
14
+ * tag should be used within The Loop.
15
+ *
16
+ * @since 0.1
17
+ * @uses get_avatar() Gets the current author's avatar.
18
+ * @uses get_the_author_meta() Grabs information about the author.
19
+ */
20
+ function members_author_profile() { ?>
21
+ <div class="author-profile vcard">
22
+ <?php echo get_avatar( get_the_author_meta( 'user_email' ), '100', '', get_the_author_meta( 'display_name' ) ); ?>
23
+ <h4 class="author-name fn n"><?php the_author_posts_link(); ?></h4>
24
+ <p class="author-description author-bio">
25
+ <?php the_author_meta( 'description' ); ?>
26
+ </p>
27
+ </div>
28
+ <?php
29
+ }
30
+
31
+ if ( !function_exists( 'has_role' ) ) {
32
+
33
+ /**
34
+ * Checks if a given ID of a user has a specific role.
35
+ *
36
+ * @since 0.1
37
+ * @uses WP_User() Gets a user object based on an ID.
38
+ * @param $role string Role to check for against the user.
39
+ * @param $user_id int The ID of the user to check.
40
+ * @return true|false bool Whether the user has the role.
41
+ */
42
+ function has_role( $role = '', $user_id = '' ) {
43
+
44
+ /* If no role or user ID was added, return false. */
45
+ if ( !$role || !$user_id )
46
+ return false;
47
+
48
+ /* Make sure the ID is an integer. */
49
+ $user_id = (int)$user_id;
50
+
51
+ /* Get the user object. */
52
+ $user = new WP_User( $user_id );
53
+
54
+ /* If the user has the role, return true. */
55
+ if ( $user->has_cap( $role ) )
56
+ return true;
57
+
58
+ /* Return false if the user doesn't have the role. */
59
+ return false;
60
+ }
61
+ }
62
+
63
+ if ( !function_exists( 'current_user_has_role' ) ) {
64
+
65
+ /**
66
+ * Checks if the currently logged-in user has a specific role.
67
+ *
68
+ * @since 0.1
69
+ * @uses current_user_can() Checks whether the user has the given role.
70
+ * @param $role string The role to check for.
71
+ * @return true|false bool Whether the user has the role.
72
+ */
73
+ function current_user_has_role( $role = '' ) {
74
+
75
+ /* If no role was input, return false. */
76
+ if ( !$role )
77
+ return false;
78
+
79
+ /* If the current user has the role, return true. */
80
+ if ( current_user_can( $role ) )
81
+ return true;
82
+
83
+ /* If the current user doesn't have the role, return false. */
84
+ return false;
85
+ }
86
+ }
87
+
88
+ ?>
components/widgets/login.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Creates a widget that allows users to add a login form to a widget area.
4
+ *
5
+ * @package Members
6
+ * @subpackage Components
7
+ */
8
+
9
+ class Members_Widget_Login extends WP_Widget {
10
+
11
+ function Members_Widget_Login() {
12
+ $widget_ops = array( 'classname' => 'login', 'description' => __('A widget that allows users to log into your site.', 'widgets-reloaded') );
13
+ $control_ops = array( 'width' => 700, 'height' => 350, 'id_base' => 'members-widget-login' );
14
+ $this->WP_Widget( 'members-widget-login', __('Login Form', 'widgets-reloaded'), $widget_ops, $control_ops );
15
+ }
16
+
17
+ function widget( $args, $instance ) {
18
+ global $user_identity, $user_ID;
19
+
20
+ extract( $args );
21
+
22
+ $title = apply_filters( 'widget_title', $instance['title'] );
23
+
24
+ $username_label = $instance['username_label'];
25
+ $password_label = $instance['password_label'];
26
+ $submit_text = $instance['submit_text'];
27
+ $remember_text = $instance['remember_text'];
28
+
29
+ $logged_in_text = apply_filters( 'widget_text', $instance['logged_in_text'] );
30
+ $logged_out_text = apply_filters( 'widget_text', $instance['logged_out_text'] );
31
+
32
+ $show_avatar = isset( $instance['show_avatar'] ) ? $instance['show_avatar'] : false;
33
+
34
+ echo $before_widget;
35
+
36
+ if ( $title )
37
+ echo "\n\t\t\t" . $before_title . $title . $after_title;
38
+
39
+ if ( is_user_logged_in() ) {
40
+
41
+ if ( $show_avatar )
42
+ echo get_avatar( $user_ID );
43
+
44
+ if ( $logged_in_text )
45
+ echo $logged_in_text;
46
+
47
+ }
48
+ else {
49
+ if ( $show_avatar )
50
+ echo get_avatar( $user_ID );
51
+
52
+ if ( $logged_out_text )
53
+ echo $logged_out_text;
54
+
55
+ $login = '<div class="clear log-in login-form">';
56
+
57
+ $login .= '<form class="log-in" action="' . get_bloginfo( 'wpurl' ) . '/wp-login.php" method="post">';
58
+
59
+ $login .= '<p class="text-input">';
60
+ $login .= '<label class="text" for="log">' . $username_label . '</label>';
61
+ $login .= '<input class="field" type="text" name="log" id="log" value="' . esc_attr( $user_login ) . '" size="23" />';
62
+ $login .= '</p>';
63
+
64
+ $login .= '<p class="text-input">';
65
+ $login .= '<label class="text" for="pwd">' . $password_label . '</label>';
66
+ $login .= '<input class="field" type="password" name="pwd" id="pwd" size="23" />';
67
+ $login .= '</p>';
68
+
69
+ $login .= '<div class="clear">';
70
+ $login .= '<input type="submit" name="submit" value="' . $submit_text . '" class="log-in" />';
71
+ $login .= '<label class="remember"><input name="rememberme" id="rememberme" type="checkbox" checked="checked" value="forever" /> ' . $remember_text . '</label>';
72
+ $login .= '<input type="hidden" name="redirect_to" value="' . $_SERVER['REQUEST_URI'] . '"/>';
73
+ $login .= '</div>';
74
+
75
+ $login .= '</form>';
76
+
77
+ $login .= '</div>';
78
+
79
+ echo $login;
80
+ }
81
+
82
+ echo $after_widget;
83
+ }
84
+
85
+ function update( $new_instance, $old_instance ) {
86
+ $instance = $old_instance;
87
+ $instance['title'] = strip_tags( $new_instance['title'] );
88
+ $instance['username_label'] = strip_tags( $new_instance['username_label'] );
89
+ $instance['password_label'] = strip_tags( $new_instance['password_label'] );
90
+ $instance['submit_text'] = strip_tags( $new_instance['submit_text'] );
91
+ $instance['remember_text'] = strip_tags( $new_instance['remember_text'] );
92
+ $instance['show_avatar'] = $new_instance['show_avatar'];
93
+
94
+ if ( current_user_can('unfiltered_html') ) {
95
+ $instance['logged_in_text'] = $new_instance['logged_in_text'];
96
+ $instance['logged_out_text'] = $new_instance['logged_out_text'];
97
+ }
98
+ else {
99
+ $instance['logged_in_text'] = wp_filter_post_kses( $new_instance['logged_in_text'] );
100
+ $instance['logged_out_text'] = wp_filter_post_kses( $new_instance['logged_out_text'] );
101
+ }
102
+
103
+ return $instance;
104
+ }
105
+
106
+ function form( $instance ) {
107
+
108
+ //Defaults
109
+ $defaults = array(
110
+ 'title' => __('Log In', 'widgets-reloaded'),
111
+ 'username_label' => __('Username:', 'members'),
112
+ 'password_label' => __('Password', 'members'),
113
+ 'submit_text' => __('Log In', 'members'),
114
+ 'remember_text' => __('Remember me?', 'members'),
115
+ 'show_avatar' => true,
116
+ 'logged_out_text' => __('Please log into the site.', 'members'),
117
+ 'logged_in_text' => __('You are currently logged in.', 'members')
118
+ );
119
+
120
+ $instance = wp_parse_args( (array) $instance, $defaults );
121
+ $logged_in_text = format_to_edit( $instance['logged_in_text'] );
122
+ $logged_out_text = format_to_edit( $instance['logged_out_text'] ); ?>
123
+
124
+ <div style="float: left; width: 48%;">
125
+ <p>
126
+ <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e('Title:', 'widgets-reloaded'); ?></label>
127
+ <input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" style="width:100%;" />
128
+ </p>
129
+
130
+ <p>
131
+ <label for="<?php echo $this->get_field_id( 'logged_out_text' ); ?>"><?php _e('Logged out text:', 'members'); ?></label>
132
+ <textarea class="widefat" rows="3" cols="20" id="<?php echo $this->get_field_id('logged_out_text'); ?>" name="<?php echo $this->get_field_name('logged_out_text'); ?>" style="width:100%;"><?php echo $logged_out_text; ?></textarea>
133
+ </p>
134
+
135
+ <p>
136
+ <label for="<?php echo $this->get_field_id( 'logged_in_text' ); ?>"><?php _e('Logged in text:', 'members'); ?></label>
137
+ <textarea class="widefat" rows="3" cols="20" id="<?php echo $this->get_field_id('logged_in_text'); ?>" name="<?php echo $this->get_field_name('logged_in_text'); ?>" style="width:100%;"><?php echo $logged_in_text; ?></textarea>
138
+ </p>
139
+ </div>
140
+
141
+ <div style="float: right; width: 48%;">
142
+
143
+ <p>
144
+ <label for="<?php echo $this->get_field_id( 'show_avatar' ); ?>">
145
+ <input class="checkbox" type="checkbox" <?php checked( $instance['show_avatar'], true ); ?> id="<?php echo $this->get_field_id( 'show_avatar' ); ?>" name="<?php echo $this->get_field_name( 'show_avatar' ); ?>" /> <?php _e('Display avatar?', 'widgets-reloaded'); ?></label>
146
+ </p>
147
+ <p>
148
+ <label for="<?php echo $this->get_field_id( 'username_label' ); ?>"><?php _e('Username Label:', 'widgets-reloaded'); ?></label>
149
+ <input id="<?php echo $this->get_field_id( 'username_label' ); ?>" name="<?php echo $this->get_field_name( 'username_label' ); ?>" value="<?php echo $instance['username_label']; ?>" style="width:100%;" />
150
+ </p>
151
+ <p>
152
+ <label for="<?php echo $this->get_field_id( 'password_label' ); ?>"><?php _e('Password Label:', 'widgets-reloaded'); ?></label>
153
+ <input id="<?php echo $this->get_field_id( 'password_label' ); ?>" name="<?php echo $this->get_field_name( 'password_label' ); ?>" value="<?php echo $instance['password_label']; ?>" style="width:100%;" />
154
+ </p>
155
+
156
+ <p>
157
+ <label for="<?php echo $this->get_field_id( 'submit_text' ); ?>"><?php _e('Submit Text:', 'widgets-reloaded'); ?></label>
158
+ <input id="<?php echo $this->get_field_id( 'submit_text' ); ?>" name="<?php echo $this->get_field_name( 'submit_text' ); ?>" value="<?php echo $instance['submit_text']; ?>" style="width:100%;" />
159
+ </p>
160
+ <p>
161
+ <label for="<?php echo $this->get_field_id( 'remember_text' ); ?>"><?php _e('Remember User Text:', 'widgets-reloaded'); ?></label>
162
+ <input id="<?php echo $this->get_field_id( 'remember_text' ); ?>" name="<?php echo $this->get_field_name( 'remember_text' ); ?>" value="<?php echo $instance['remember_text']; ?>" style="width:100%;" />
163
+ </p>
164
+ </div>
165
+
166
+ <div>
167
+
168
+ </div>
169
+ <div style="clear:both;">&nbsp;</div>
170
+ <?php
171
+ }
172
+ }
173
+
174
+ ?>
components/widgets/users.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Creates a widget that allows users to list users of their site.
4
+ *
5
+ * @package Members
6
+ * @subpackage Components
7
+ */
8
+
9
+ class Members_Widget_Users extends WP_Widget {
10
+
11
+ function Members_Widget_Users() {
12
+ $widget_ops = array( 'classname' => 'users', 'description' => __('An advanced widget that gives you total control over the output of your user lists.','members') );
13
+ $control_ops = array( 'width' => 250, 'height' => 350, 'id_base' => 'members-widget-users' );
14
+ $this->WP_Widget( 'members-widget-users', __('Users', 'members'), $widget_ops, $control_ops );
15
+ }
16
+
17
+ function widget( $args, $instance ) {
18
+
19
+ extract( $args, EXTR_SKIP );
20
+
21
+ $title = apply_filters('widget_title', $instance['title'] );
22
+ $limit = $instance['limit'];
23
+ $order = $instance['order'];
24
+ $orderby = $instance['orderby'];
25
+ $exclude = $instance['exclude'];
26
+ $include = $instance['include'];
27
+ $show_fullname = isset( $instance['show_fullname'] ) ? $instance['show_fullname'] : false;
28
+
29
+ $users = array(
30
+ 'limit' => $limit,
31
+ 'order' => $order,
32
+ 'orderby' => $orderby,
33
+ 'include' => $include,
34
+ 'exclude' => $exclude,
35
+ 'show_fullname' => $show_fullname,
36
+ 'echo' => 0,
37
+ );
38
+
39
+ echo $before_widget;
40
+
41
+ if ( $title )
42
+ echo "\n\t\t\t" . $before_title . $title . $after_title;
43
+
44
+ echo "\n\t\t\t" . '<ul class="xoxo users">';
45
+
46
+ echo "\n\t\t\t\t" . str_replace( array( "\r", "\n", "\t" ), '', members_list_users( $users ) );
47
+
48
+ echo "\n\t\t\t" . '</ul><!-- .xoxo .users -->';
49
+
50
+ echo $after_widget;
51
+ }
52
+
53
+ function update( $new_instance, $old_instance ) {
54
+ $instance = $old_instance;
55
+ $instance['title'] = strip_tags( $new_instance['title'] );
56
+ $instance['limit'] = strip_tags( $new_instance['limit'] );
57
+ $instance['include'] = strip_tags( $new_instance['include'] );
58
+ $instance['exclude'] = strip_tags( $new_instance['exclude'] );
59
+ $instance['order'] = $new_instance['order'];
60
+ $instance['orderby'] = $new_instance['orderby'];
61
+ $instance['show_fullname'] = $new_instance['show_fullname'];
62
+
63
+ return $instance;
64
+ }
65
+
66
+ function form( $instance ) {
67
+
68
+ //Defaults
69
+ $defaults = array( 'title' => __('Users', 'members'), 'show_fullname' => true, 'order' => 'ASC', 'orderby' => 'display_name' );
70
+ $instance = wp_parse_args( (array) $instance, $defaults ); ?>
71
+
72
+ <p>
73
+ <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e('Title:', 'members'); ?></label>
74
+ <input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" style="width:99%;" />
75
+ </p>
76
+ <p>
77
+ <label for="<?php echo $this->get_field_id( 'limit' ); ?>"><?php _e('Limit:', 'members'); ?> <code>limit</code></label>
78
+ <input id="<?php echo $this->get_field_id( 'limit' ); ?>" name="<?php echo $this->get_field_name( 'limit' ); ?>" value="<?php echo $instance['limit']; ?>" style="width:99%;" />
79
+ </p>
80
+ <p>
81
+ <label for="<?php echo $this->get_field_id( 'order' ); ?>"><?php _e('Order:', 'widgets-reloaded'); ?> <code>order</code></label>
82
+ <select id="<?php echo $this->get_field_id( 'order' ); ?>" name="<?php echo $this->get_field_name( 'order' ); ?>" class="widefat" style="width:100%;">
83
+ <option <?php if ( 'ASC' == $instance['order'] ) echo 'selected="selected"'; ?>>ASC</option>
84
+ <option <?php if ( 'DESC' == $instance['order'] ) echo 'selected="selected"'; ?>>DESC</option>
85
+ </select>
86
+ </p>
87
+ <p>
88
+ <label for="<?php echo $this->get_field_id( 'orderby' ); ?>"><?php _e('Order By:', 'widgets-reloaded'); ?> <code>orderby</code></label>
89
+ <select id="<?php echo $this->get_field_id( 'orderby' ); ?>" name="<?php echo $this->get_field_name( 'orderby' ); ?>" class="widefat" style="width:100%;">
90
+ <option <?php if ( 'display_name' == $instance['orderby'] ) echo 'selected="selected"'; ?>>display_name</option>
91
+ <option <?php if ( 'ID' == $instance['orderby'] ) echo 'selected="selected"'; ?>>ID</option>
92
+ <option <?php if ( 'user_login' == $instance['orderby'] ) echo 'selected="selected"'; ?>>user_login</option>
93
+ </select>
94
+ </p>
95
+ <p>
96
+ <label for="<?php echo $this->get_field_id( 'include' ); ?>"><?php _e('Include:', 'members'); ?> <code>include</code></label>
97
+ <input id="<?php echo $this->get_field_id( 'include' ); ?>" name="<?php echo $this->get_field_name( 'include' ); ?>" value="<?php echo $instance['include']; ?>" style="width:99%;" />
98
+ </p>
99
+ <p>
100
+ <label for="<?php echo $this->get_field_id( 'exclude' ); ?>"><?php _e('Exclude:', 'members'); ?> <code>exclude</code></label>
101
+ <input id="<?php echo $this->get_field_id( 'exclude' ); ?>" name="<?php echo $this->get_field_name( 'exclude' ); ?>" value="<?php echo $instance['exclude']; ?>" style="width:99%;" />
102
+ </p>
103
+ <p>
104
+ <label for="<?php echo $this->get_field_id( 'show_fullname' ); ?>">
105
+ <input class="checkbox" type="checkbox" <?php checked( $instance['show_fullname'], true ); ?> id="<?php echo $this->get_field_id( 'show_fullname' ); ?>" name="<?php echo $this->get_field_name( 'show_fullname' ); ?>" /> <?php _e('Show full name?', 'members'); ?> <code>show_fullname</code></label>
106
+ </p>
107
+
108
+ <div style="clear:both;">&nbsp;</div>
109
+ <?php
110
+ }
111
+ }
112
+
113
+ ?>
functions-admin.php ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Functions that may be used across a variety of components, so they should always
4
+ * be loaded for use in the admin. Many of the functions here deal with setting up, getting,
5
+ * and checking for capabilities. Since the management of capabilities is at the heart of this
6
+ * entire plugin, these are probably the plugin functions you'll use most when developing
7
+ * a custom component for the plugin.
8
+ *
9
+ * @package Members
10
+ */
11
+
12
+ /* Disables the old levels from being seen. If you need them, use remove_filter() to add display back. */
13
+ add_filter( 'members_get_capabilities', 'members_remove_old_levels' );
14
+
15
+ /**
16
+ * The function that makes this plugin what it is. It returns all of our capabilities
17
+ * in a nicely-formatted, alphabetized array with no duplicate capabilities. It pulls
18
+ * from three different functions to make sure we get all of the capabilities that
19
+ * we need for use in the plugin components.
20
+ *
21
+ * @since 0.1
22
+ * @uses members_get_default_capabilities() Gets an array of WP's default capabilities.
23
+ * @uses members_get_role_capabilities() Gets an array of all the capabilities currently mapped to a role.
24
+ * @uses members_get_additional_capabilities() Gets an array of capabilities added by the plugin.
25
+ * @return $capabilities array An array containing all of the capabilities.
26
+ */
27
+ function members_get_capabilities() {
28
+
29
+ /* Capabilities array. */
30
+ $capabilities = array();
31
+
32
+ /* Grab the default capabilities (these are set by the plugin so the user doesn't lose them). */
33
+ $default_caps = members_get_default_capabilities();
34
+
35
+ /* Get the user capabilities that are already set. */
36
+ $role_caps = members_get_role_capabilities();
37
+
38
+ /* Gets capabilities added by the plugin. */
39
+ $plugin_caps = members_get_additional_capabilities();
40
+
41
+ /* Merge all the capability arrays (current role caps, plugin caps, and default WP caps) together. */
42
+ $capabilities = array_merge( $default_caps, $role_caps, $plugin_caps );
43
+
44
+ /* Apply filters to the array of capabilities. Devs should respect the available capabilities and return an array. */
45
+ $capabilities = apply_filters( 'members_get_capabilities', $capabilities );
46
+
47
+ /* Sort the capabilities by name so they're easier to read when shown on the screen. */
48
+ sort( $capabilities );
49
+
50
+ /* Return the array of capabilities, making sure we have no duplicates. */
51
+ return array_unique( $capabilities );
52
+ }
53
+
54
+ /**
55
+ * Gets an array of capabilities according to each user role. Each role will return its caps,
56
+ * which are then added to the overall $capabilities array.
57
+ *
58
+ * Note that if no role has the capability, it technically no longer exists. Since this could be
59
+ * a problem with folks accidentally deleting the default WordPress capabilities, the
60
+ * members_default_capabilities() will return those all the defaults.
61
+ *
62
+ * @since 0.1
63
+ * @return $capabilities array All the capabilities of all the user roles.
64
+ * @global $wp_roles array Holds all the roles for the installation.
65
+ */
66
+ function members_get_role_capabilities() {
67
+ global $wp_roles;
68
+
69
+ $capabilities = array();
70
+
71
+ /* Loop through each role object because we need to get the caps. */
72
+ foreach ( $wp_roles->role_objects as $key => $role ) {
73
+
74
+ /* Roles without capabilities will cause an error, so we need to check if $role->capabilities is an array. */
75
+ if ( is_array( $role->capabilities ) ) {
76
+
77
+ /* Loop through the role's capabilities and add them to the $capabilities array. */
78
+ foreach ( $role->capabilities as $cap => $grant )
79
+ $capabilities[$cap] = $cap;
80
+ }
81
+ }
82
+
83
+ /* Return the capabilities array. */
84
+ return $capabilities;
85
+ }
86
+
87
+ /**
88
+ * Additional capabilities provided by the plugin that gives users permissions
89
+ * to handle certain components of the plugin.
90
+ *
91
+ * @todo Integrate 'edit_roles' into the settings. It should be a priority on initial setup.
92
+ * @todo Move each capability within its component. Use the 'members_get_capabilities' filter hook to add them.
93
+ *
94
+ * @since 0.1
95
+ */
96
+ function members_get_additional_capabilities() {
97
+
98
+ $capabilities = array(
99
+ 'create_roles', // Ability to create new roles
100
+ 'delete_roles', // Ability to delete roles
101
+ 'edit_roles', // Ability to edit a role's caps
102
+ 'restrict_content' // Ability to restrict content (content permissions component)
103
+ );
104
+
105
+ return $capabilities;
106
+ }
107
+
108
+ /**
109
+ * Make sure we keep the default capabilities in case users screw 'em up. A user could
110
+ * easily remove a useful WordPress capability from all roles. When this happens, the capability
111
+ * is no longer stored in any of the roles, so it basically doesn't exist. This function will house
112
+ * all of the default WordPress capabilities in case this scenario comes into play.
113
+ *
114
+ * For those reading this note, yes, I did "accidentally" remove all capabilities from my administrator
115
+ * account when developing this plugin. And yes, that was fun putting back together. ;)
116
+ *
117
+ * The Codex has a list of all the defaults:
118
+ * @link http://codex.wordpress.org/Roles_and_Capabilities#Capabilities
119
+ *
120
+ * @since 0.1
121
+ * @return $defaults array All the default WordPress capabilities.
122
+ */
123
+ function members_get_default_capabilities() {
124
+
125
+ /* Create an array of all the default WordPress capabilities so the user doesn't accidentally get rid of them. */
126
+ $defaults = array(
127
+ 'activate_plugins',
128
+ 'create_users',
129
+ 'delete_others_pages',
130
+ 'delete_others_posts',
131
+ 'delete_pages',
132
+ 'delete_plugins',
133
+ 'delete_posts',
134
+ 'delete_private_pages',
135
+ 'delete_private_posts',
136
+ 'delete_published_pages',
137
+ 'delete_published_posts',
138
+ 'delete_users',
139
+ 'edit_dashboard',
140
+ 'edit_files',
141
+ 'edit_others_pages',
142
+ 'edit_others_posts',
143
+ 'edit_pages',
144
+ 'edit_plugins',
145
+ 'edit_posts',
146
+ 'edit_private_pages',
147
+ 'edit_private_posts',
148
+ 'edit_published_pages',
149
+ 'edit_published_posts',
150
+ 'edit_themes',
151
+ 'edit_users',
152
+ 'import',
153
+ 'install_plugins',
154
+ 'install_themes',
155
+ 'manage_categories',
156
+ 'manage_links',
157
+ 'manage_options',
158
+ 'moderate_comments',
159
+ 'publish_pages',
160
+ 'publish_posts',
161
+ 'read',
162
+ 'read_private_pages',
163
+ 'read_private_posts',
164
+ 'switch_themes',
165
+ 'unfiltered_html',
166
+ 'unfiltered_upload',
167
+ 'update_plugins',
168
+ 'update_themes',
169
+ 'upload_files'
170
+ );
171
+
172
+ /* Return the array of default capabilities. */
173
+ return $defaults;
174
+ }
175
+
176
+ /**
177
+ * Checks if a specific capability has been given to at least one role. If it has,
178
+ * return true. Else, return false.
179
+ *
180
+ * @since 0.1
181
+ * @uses members_get_role_capabilities() Checks for capability in array of role caps.
182
+ * @param $cap string Name of the capability to check for.
183
+ * @return true|false bool Whether the capability has been given to a role.
184
+ */
185
+ function members_check_for_cap( $cap = '' ) {
186
+
187
+ /* Without a capability, we have nothing to check for. Just return false. */
188
+ if ( !$cap )
189
+ return false;
190
+
191
+ /* Gets capabilities that are currently mapped to a role. */
192
+ $caps = members_get_role_capabilities();
193
+
194
+ /* If the capability has been given to at least one role, return true. */
195
+ if ( in_array( $cap, $caps ) )
196
+ return true;
197
+
198
+ /* If no role has been given the capability, return false. */
199
+ return false;
200
+ }
201
+
202
+ /**
203
+ * Old WordPress levels system. This is mostly useful for filtering out the
204
+ * levels when shown in admin screen. Plugins shouldn't rely on these levels
205
+ * to create permissions for users. They should move to the newer system of
206
+ * checking for a specific capability instead.
207
+ *
208
+ * @since 0.1
209
+ * @return array Old user levels.
210
+ */
211
+ function members_get_old_levels() {
212
+ return array( 'level_0', 'level_1', 'level_2', 'level_3', 'level_4', 'level_5', 'level_6', 'level_7', 'level_8', 'level_9', 'level_10' );
213
+ }
214
+
215
+ /**
216
+ * Get rid of levels since these are mostly useless in newer versions of WordPress.
217
+ *
218
+ * To remove this filter:
219
+ * remove_filter( 'members_get_capabilities', 'members_remove_old_levels' );
220
+ *
221
+ * @since 0.1
222
+ * @param $capabilities array All of the combined capabilities.
223
+ * @return $capabilities array Capabilities with old user levels removed.
224
+ */
225
+ function members_remove_old_levels( $capabilities ) {
226
+ return array_diff( $capabilities, members_get_old_levels() );
227
+ }
228
+
229
+ /**
230
+ * A function for displaying messages in the admin. It will wrap the message
231
+ * in the appropriate <div> with the custom class entered. The updated class
232
+ * will be added if no $class is given.
233
+ *
234
+ * @since 0.1
235
+ * @param $class string Class the <div> should have.
236
+ * @param $message string The text that should be displayed.
237
+ */
238
+ function members_admin_message( $class = '', $message = '' ) {
239
+ if ( !$class )
240
+ $class = 'updated fade below-h2';
241
+
242
+ echo "<div class='{$class}' style='padding: 5px 10px;'>";
243
+ echo $message;
244
+ echo '</div>';
245
+ }
246
+
247
+ /**
248
+ * Members plugin nonce function. This is to help with securely making sure
249
+ * forms have been processed from the correct place.
250
+ *
251
+ * @since 0.1
252
+ * @param $action string Additional action to add to the nonce.
253
+ */
254
+ function members_get_nonce( $action = '' ) {
255
+ if ( $action )
256
+ return "members-component-action_{$action}";
257
+ else
258
+ return "members-plugin";
259
+ }
260
+
261
+ ?>
functions.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Functions that may be used across a variety of components, so they should always
4
+ * be loaded for use on the front end of the site.
5
+ *
6
+ * @todo Decide whether Template Tags is a useful enough component to stand alone.
7
+ * The Widgets and Shortcodes components both require the use of these functions here,
8
+ * which should be template tags.
9
+ *
10
+ * @package Members
11
+ */
12
+
13
+ /**
14
+ * Displays the login form.
15
+ *
16
+ * @since 0.1
17
+ */
18
+ function members_login_form() {
19
+ echo members_get_login_form();
20
+ }
21
+
22
+ /**
23
+ * Creates the login form.
24
+ * @todo Make each section customizable.
25
+ * @todo Clean up.
26
+ *
27
+ * @since 0.1
28
+ */
29
+ function members_get_login_form() {
30
+ global $user_identity, $user_ID;
31
+
32
+ if ( is_user_logged_in() ) {
33
+
34
+ $login = '<div class="login-form">';
35
+ $login .= '<p><strong>' . sprintf( __('Welcome, %1$s!', 'members'), $user_identity ) . '</strong></p>';
36
+ $login .= '</div>';
37
+ }
38
+ else {
39
+
40
+ $login = '<div class="log-in login-form">';
41
+
42
+ $login .= '<form class="log-in" action="' . get_bloginfo( 'wpurl' ) . '/wp-login.php" method="post">';
43
+
44
+ $login .= '<p class="text-input">';
45
+ $login .= '<label class="text" for="log">' . __('Username:', 'members') . '</label>';
46
+ $login .= '<input class="field" type="text" name="log" id="log" value="' . esc_attr( $user_login ) . '" size="23" />';
47
+ $login .= '</p>';
48
+
49
+ $login .= '<p class="text-input">';
50
+ $login .= '<label class="text" for="pwd">' . __('Password:', 'members') . '</label>';
51
+ $login .= '<input class="field" type="password" name="pwd" id="pwd" size="23" />';
52
+ $login .= '</p>';
53
+
54
+ $login .= '<div class="clear">';
55
+ $login .= '<input type="submit" name="submit" value="' . __('Log In', 'members') . '" class="log-in" />';
56
+ $login .= '<label class="remember"><input name="rememberme" id="rememberme" type="checkbox" checked="checked" value="forever" /> ' . __('Remember me', 'members') . '</label>';
57
+ $login .= '<input type="hidden" name="redirect_to" value="' . $_SERVER['REQUEST_URI'] . '"/>';
58
+ $login .= '</div>';
59
+
60
+ $login .= '</form>';
61
+
62
+ $login .= '</div>';
63
+ }
64
+
65
+ return $login;
66
+ }
67
+
68
+ /**
69
+ * Function for listing users like the WordPress function currently use for authors.
70
+ * This function is based off wp_dropdown_users() and wp_list_authors(). It is my
71
+ * hope that a wp_list_users() function eventually exists and this is no longer relevant.
72
+ *
73
+ * @todo Allow the input of a role to limit the list.
74
+ *
75
+ * @since 0.1
76
+ * @param $order string ASC or DESC order.
77
+ * @param $orderby string display_name, id, user_login
78
+ * @param $include string IDs of users to include.
79
+ * @param $exclude string IDs of users to exclude.
80
+ * @param $limit int Number of users to list.
81
+ * @param $show_fullname bool Whether to show users' full name (defaults to display name).
82
+ * @param $echo bool Whether to print the list or return for use in a function.
83
+ */
84
+ function members_list_users( $args = array() ) {
85
+ global $wpdb;
86
+
87
+ $defaults = array(
88
+ 'order' => 'ASC',
89
+ 'orderby' => 'display_name',
90
+ 'include' => '',
91
+ 'exclude' => '',
92
+ //'role' => '',
93
+ 'limit' => '',
94
+ //'optioncount' => false,
95
+ 'show_fullname' => true,
96
+ //'exclude_empty' => false,
97
+ //'exclude_admin' => true,
98
+ 'echo' => true,
99
+ );
100
+
101
+ $r = wp_parse_args( $args, $defaults );
102
+
103
+ $r = apply_filters( 'members_list_users_args', $r );
104
+
105
+ extract( $r, EXTR_SKIP );
106
+
107
+ $query = "SELECT * FROM $wpdb->users";
108
+
109
+ $query_where = array();
110
+
111
+ if ( is_array( $include ) )
112
+ $include = join( ',', $include );
113
+
114
+ $include = preg_replace( '/[^0-9,]/', '', $include ); // (int)
115
+
116
+ if ( $include )
117
+ $query_where[] = "ID IN ($include)";
118
+
119
+ if ( is_array($exclude) )
120
+ $exclude = join( ',', $exclude );
121
+
122
+ $exclude = preg_replace( '/[^0-9,]/', '', $exclude ); // (int)
123
+
124
+ if ( $exclude )
125
+ $query_where[] = "ID NOT IN ($exclude)";
126
+
127
+ if ( $query_where )
128
+ $query .= " WHERE " . join( ' AND', $query_where );
129
+
130
+ $query .= " ORDER BY $orderby $order";
131
+
132
+ if ( '' != $limit ) {
133
+ $limit = absint( $limit );
134
+ $query .= ' LIMIT ' . $limit;
135
+ }
136
+
137
+ $users = $wpdb->get_results( $query );
138
+
139
+ $output = '';
140
+
141
+ if ( !empty( $users ) ) {
142
+
143
+ foreach ( (array) $users as $user ) {
144
+
145
+ $user->ID = (int) $user->ID;
146
+
147
+ $author = get_userdata( $user->ID );
148
+
149
+ $name = $author->display_name;
150
+
151
+ if ( $show_fullname && ($author->first_name != '' && $author->last_name != '') )
152
+ $name = "$author->first_name $author->last_name";
153
+
154
+ $class = "user-{$user->ID}";
155
+
156
+ if ( is_author( $user->ID ) )
157
+ $class .= ' current-user';
158
+
159
+ if ( $hide_empty )
160
+ $output .= "<li class='$class'>$name</li>\n";
161
+ else
162
+ $output .= "<li class='$class'><a href='" . get_author_posts_url( $author->ID, $author->user_nicename ) . "' title='" . sprintf(__("Posts by %s"), esc_attr( $author->display_name ) ) . "'>$name</a></li>\n";
163
+ }
164
+ }
165
+
166
+ $output = apply_filters( 'members_list_users', $output );
167
+
168
+ if ( !$echo )
169
+ return $output;
170
+
171
+ echo $output;
172
+ }
173
+
174
+ ?>
members.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin Name: Members
4
+ * Plugin URI: http://justintadlock.com/archives/2009/09/17/members-wordpress-plugin
5
+ * Description: A user, role, and content management plugin for controlling permissions and access. A plugin for making WordPress a more powerful <acronym title="Content Management System">CMS</acronym>.
6
+ * Version: 0.1
7
+ * Author: Justin Tadlock
8
+ * Author URI: http://justintadlock.com
9
+ *
10
+ * The members plugin was created because the WordPress community is lacking
11
+ * a solid permissions plugin that is both open source and works completely within the
12
+ * confines of the APIs in WordPress. But, the plugin is so much more than just a
13
+ * plugin to control permissions. It is meant to extend WordPress by making user,
14
+ * role, and content management as simple as using the system altogether.
15
+ *
16
+ * This program is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19
+ *
20
+ * @package Members
21
+ */
22
+
23
+ /* Set constant path to the members plugin directory. */
24
+ define( MEMBERS_DIR, plugin_dir_path( __FILE__ ) );
25
+
26
+ /* Set constant path to the members plugin URL. */
27
+ define( MEMBERS_URL, plugin_dir_url( __FILE__ ) );
28
+
29
+ /* Set constant path to the members components directory. */
30
+ define( MEMBERS_COMPONENTS, MEMBERS_DIR . 'components' );
31
+
32
+ /* Launch the plugin. */
33
+ add_action( 'plugins_loaded', 'members_plugin_init' );
34
+
35
+ /**
36
+ * Initialize the plugin. This function loads the required files needed for the plugin
37
+ * to run in the proper order. Mostly, it's the function that brings the components
38
+ * system into play.
39
+ *
40
+ * @since 0.1
41
+ */
42
+ function members_plugin_init() {
43
+
44
+ /* Load global functions for the WordPress admin. */
45
+ if ( is_admin() )
46
+ require_once( MEMBERS_DIR . '/functions-admin.php' );
47
+
48
+ /* Load global functions for the front end of the site. */
49
+ else
50
+ require_once( MEMBERS_DIR . '/functions.php' );
51
+
52
+ /* Load the components system, which is the file that has all the components-related functions. */
53
+ require_once( MEMBERS_DIR . '/components.php' );
54
+
55
+ /* Members components settings page. */
56
+ add_action( 'admin_menu', 'members_settings_page_init' );
57
+ add_action( 'admin_init', 'members_register_settings' );
58
+
59
+ /* Set up globals. */
60
+ add_action( 'init', 'members_core_globals_setup', 0 );
61
+
62
+ /* Available action hook if needed by another plugin/theme to run additional functions. */
63
+ do_action( 'members_init' );
64
+ }
65
+
66
+ /**
67
+ * Set up the $members global variable. Since we'll need to have several
68
+ * different variables, it just makes sense to put them all into one place.
69
+ * Other functions will hook onto this (e.g., $members-registered_components).
70
+ *
71
+ * @since 0.1
72
+ * @global $members object The global members object.
73
+ * @global $current_user object The currently logged-in user.
74
+ */
75
+ function members_core_globals_setup() {
76
+ global $members, $current_user;
77
+
78
+ /* Get the currently logged-in user. */
79
+ $current_user = wp_get_current_user();
80
+
81
+ /* Add the currently logged-in user to our global object. */
82
+ $members->current_user = $current_user;
83
+ }
84
+
85
+ /**
86
+ * Creates the members settings/components page.
87
+ *
88
+ * @since 0.1
89
+ * @uses add_submenu_page() Creates a submenu for the Settings menu item.
90
+ */
91
+ function members_settings_page_init() {
92
+ $members_settings_page = add_submenu_page( 'options-general.php', __('Members Components', 'members'), __('Members Components', 'members'), 'activate_plugins', 'members-components', 'members_settings_page' );
93
+ }
94
+
95
+ /**
96
+ * Registers the plugin settings, which will become an array of activated components.
97
+ *
98
+ * @since 0.1
99
+ * @uses register_setting() Function for registering a setting in WordPress.
100
+ */
101
+ function members_register_settings() {
102
+ register_setting( 'members_plugin_settings', 'members_settings', 'members_settings_validate' );
103
+ }
104
+
105
+ /**
106
+ * Loads the admin screen page for selecting components for use with the plugin.
107
+ *
108
+ * @since 0.1
109
+ */
110
+ function members_settings_page() {
111
+ require_once( MEMBERS_DIR . '/settings.php' );
112
+ }
113
+
114
+ /**
115
+ * Validates the members settings. Since the settings is just a list of components,
116
+ * all we need to do here is loop through the array and check for true/false.
117
+ *
118
+ * @since 0.1
119
+ * @param $input array Values sent by the settings page.
120
+ * @return $input array Validated values to return.
121
+ */
122
+ function members_settings_validate( $input ) {
123
+ global $members_components;
124
+
125
+ if ( !is_array( $input ) )
126
+ return $input;
127
+
128
+ foreach ( $input as $value )
129
+ $input[$value] = ( $input[$value] == 1 ? 1 : 0 );
130
+
131
+ return $input;
132
+ }
133
+
134
+ ?>
readme.css ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Reset values */
2
+ html,body,div,span,object,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,samp,small,strong,sub,sup,tt,var,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;vertical-align:baseline;outline:none;font-size:100%;background:transparent;border:none;text-decoration:none}b,i,hr,u,center,menu,layer,s,strike,font,xmp{margin:0;padding:0;vertical-align:baseline;outline:none;font-size:100%;font-weight:normal;font-style:normal;background:transparent;border:none;text-decoration:none}font{color:#333}center{text-align:left}body{line-height:25px;font-family:Cambria,Georgia,Times,"Times New Roman",serif;color:#333;background:#fff}h1,h2,h3,h4,h5,h6{font-style:normal;font-weight:normal;margin:0 0 25px 0}h1{font-size:1.8em}h2{font-size:1.7em}h3{font-size:1.55em;}h4{font-size:1.4em}h5{font-size:1.25em}h6{font-size:1.1em}p{margin:0 0 25px 0}ol,ul{list-style:none}ul{list-style:disc;margin:0 0 25px 2.5em}ol{list-style-type:decimal;margin:0 0 25px 3em}ol ol{list-style:upper-roman}ol ol ol{list-style:lower-roman}ol ol ol ol{list-style:upper-alpha}ol ol ol ol ol{list-style:lower-alpha}ul ul,ol ol,ul ol,ol ul{margin-bottom:0}dl{margin:0 0 25px 5px}dl dt{font-weight:bold;margin:10px 0 0 0}dl dd{margin:5px 0 0 1.5em}strong{font-weight:bold}strong strong{font-weight:normal}em,cite{font-style:italic}em em,cite cite{font-style:normal}abbr{cursor:help}acronym{text-transform:uppercase;border-bottom:1px dashed #666;cursor:help}big{font-size:120%}small,sup,sub{font-size:80%}sup{vertical-align:baseline;position:relative;bottom:0.3em}sub{vertical-align:baseline;position:relative;top:0.3em}address{font-style:italic;margin:0 0 25px 0}li address,dd address{margin:0}blockquote{margin:0 25px;font-style:normal}blockquote em,blockquote cite{font-style:italic}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}a{cursor:pointer}a img{border:none}pre{overflow:auto;font:.9em Monaco,monospace,Courier,"Courier New";line-height:25px;margin-bottom:25px;padding:10px}code{font:.9em Monaco,monospace,Courier,"Courier New"}pre code{font-size:1em}ins,dfn{font-style:italic;text-decoration:none;border-bottom:1px solid #666}del{text-decoration:line-through}object{margin-bottom:25px}input,textarea{font-size:1em;font-family:Cambria,Georgia,Times,"Times New Roman",serif;padding:3px}:focus{outline:none}form label{cursor:pointer}option{padding:1px 2px}table{border-collapse:collapse;border-spacing:0;margin-bottom:25px}th,td{text-align:left}hr{margin-bottom:25px}img.wp-smiley{max-height:12px;margin:0;padding:0;border:none}.gallery{display:block;text-align:center;margin-bottom:25px !important}.alignleft,.left{float:left;margin-right:20px}.alignright,.right{float:right;margin-left:20px}.aligncenter,.center{display:block;margin:0 auto 25px auto}.alignnone,.block{clear:both;margin:0 0 25px 0}.clear{clear:both}img.alignleft,img.alignright{display:inline}
3
+
4
+ body {
5
+ width: 750px;
6
+ margin: 36px auto 60px auto;
7
+ font: 15px/21px Arial, 'Helvetica Neue', Helvetica, sans-serif;
8
+ font: 16px/25px Georgia, Times, 'Times New Roman', serif;
9
+ }
10
+ /* Links */
11
+ a:link, a:visited {
12
+ color: #2f6eb9;
13
+ text-decoration: none;
14
+ }
15
+ a:hover, a:active {
16
+ text-decoration: underline;
17
+ }
18
+ /* Headers */
19
+ h1, h2, h3, h4, h5, h6 {
20
+ margin: 40px 0 30px 0;
21
+ color: #000;
22
+ font-weight: bold;
23
+ font-family: Arial, sans-serif;
24
+ }
25
+ h3 {
26
+ font-weight: normal;
27
+ font-style: italic;
28
+ font-family: Georgia, Times, 'Times New Roman', serif;
29
+ }
30
+ h1 {
31
+ margin-top: 80px;
32
+ font-size: 2.2em;
33
+ }
34
+ code {
35
+ padding: 0 3px;
36
+ background: #eee;
37
+ }
38
+ pre code {
39
+ padding: 0;
40
+ }
41
+ pre {
42
+ padding: 9px;
43
+ background: #eee;
44
+ border: 1px solid #ccc;
45
+ }
46
+ ul {
47
+ list-style: square;
48
+ }
49
+ p.first {
50
+ font-size: 21px;
51
+ }
52
+ p.second {
53
+ font-size: 15px;
54
+ }
55
+ ul.space li {
56
+ margin-bottom: 10px;
57
+ }
58
+ .section {
59
+ overflow: hidden;
60
+ }
61
+
62
+ .columns-2 {
63
+ float: left;
64
+ width: 350px;
65
+ margin: 0 0 21px 25px;
66
+ }
67
+ .columns-3 {
68
+ float: left;
69
+ width: 230px;
70
+ margin: 0 0 21px 20px;
71
+ }
72
+ /* Warnings/Alerts */
73
+ .warning, .alert {
74
+ padding: 6px 9px;
75
+ background: #fffbbc;
76
+ border: 1px solid #E6DB55;
77
+ }
readme.html ADDED
@@ -0,0 +1,376 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
5
+ <title>A guide to the Members plugin</title>
6
+
7
+ <link rel="stylesheet" href="readme.css" type="text/css" media="screen" />
8
+
9
+ </head>
10
+ <body>
11
+
12
+ <h1>A guide to the Members plugin</h1>
13
+
14
+ <p class="first">The <em>Members</em> plugin is meant to be a complete user, role, and content management plugin for WordPress. Its purpose is to give you fine-grained control over who has access to what.</p>
15
+
16
+ <p class="second">Right now, it's in the early stages of development. It's my hope that this provides that true <acronym title="Content Management System">CMS</acronym> experience that many users long for in WordPress. There's a long road ahead, and I hope you join me for the ride.</p>
17
+
18
+ <h2>The plugin documentation</h2>
19
+
20
+ <p>Use the links below to navigate to a specific section in the documentation:</p>
21
+
22
+ <ul>
23
+ <li><a href="#users-roles-caps">The relationship of users, roles, and capabilities</a></li>
24
+ <li><a href="#install">How to install the plugin</a></li>
25
+ <li><a href="#how-to">How to use the plugin</a></li>
26
+ <li>Components
27
+ <ul>
28
+ <li><a href="#edit-roles">Edit Roles component</a></li>
29
+ <li><a href="#new-roles">New Roles component</a></li>
30
+ <li><a href="#content-permissions">Content Permissions component</a></li>
31
+ <li><a href="#shortcodes">Shortcodes component</a>
32
+ <ul>
33
+ <li><a href="#access">[access]</a></li>
34
+ <li><a href="#get-avatar">[get_avatar]</a></li>
35
+ <li><a href="#is-user-logged-in">[is_user_logged_in]</a></li>
36
+ <li><a href="#feed">[feed]</a></li>
37
+ <li><a href="#login-form">[login-form]</a></li>
38
+ </ul>
39
+ </li>
40
+ <li><a href="#template-tags">Template Tags component</a>
41
+ <ul>
42
+ <li><a href="#current_user_has_role">current_user_has_role()</a></li>
43
+ <li><a href="#has_role">has_role()</a></li>
44
+ <li><a href="#members_list_users">members_list_users()</a></li>
45
+ <li><a href="#members_author_profile">members_author_profile()</a></li>
46
+ </ul>
47
+ </li>
48
+ <li><a href="#widgets">Widgets component</a>
49
+ <ul>
50
+ <li><a href="#login-widget">Login Form widget</a></li>
51
+ <li><a href="#users-widget">Users widget</a></li>
52
+ </ul>
53
+ </li>
54
+ <li><a href="#private-blog">Private Blog component</a></li>
55
+ </ul>
56
+ </li>
57
+ <li><a href="#capability-check">Checking if the current user has a capability</a></li>
58
+ <li>Plugin/theme integration for developers
59
+ <ul>
60
+ <li><a href="#components-api">Creating custom components</a></li>
61
+ <li><a href="#filter-caps">Adding new capabilities</a></li>
62
+ <li><a href="#cap-check">Checking for capabilities</a></li>
63
+ </ul>
64
+ </li>
65
+ <li><a href="#old-levels">Need the old user levels system?</a></li>
66
+ <li><a href="#plugin-support">Plugin support</a></li>
67
+ <li><a href="#copyright">Copyright &amp; License</a></li>
68
+ </ul>
69
+
70
+ <h2 id="users-roles-caps">The relationship of users, roles, and capabilities</h2>
71
+
72
+ <p>This is the most important thing to understand with this plugin. It's so important that I took the time out of my day to write a complete tutorial on understanding this: <a href="http://justintadlock.com/archives/2009/08/30/users-roles-and-capabilities-in-wordpress" title="Users, roles, and capabilities in WordPress">Users, roles, and capabilities in WordPress</a>. If you don't understand this concept, you won't understand what this plugin does. This is not a concept created by the plugin. This is how it's done in WordPress.</p>
73
+
74
+ <p>I highly recommend reading that blog post, but here's the short version:</p>
75
+
76
+ <ul>
77
+ <li><strong>Users</strong> are people that have registered on your site. I'm sure you already knew that. In WordPress, users are assigned a specific role. This role defines what the user can/can't do.</li>
78
+ <li><strong>Roles</strong> are a way of grouping users. Each user on your site will have a specific role. Roles are a set of capabilities. It is important to note that <strong>roles are not hierarchical</strong>. For example, "Administrator" is not higher than "Subscriber" in WordPress. You could literally give the Subscriber role more capabilities than the Administrator role. It's very important that you grasp this concept.</li>
79
+ <li><strong>Capabilities</strong> give meaning to roles. It's a permissions system. They're a way of saying a role <em>can</em> do something or a role <em>can't</em> do something (e.g., Role A can <code>edit_posts</code>, Role B can't <code>activate_plugins</code>, etc.).</li>
80
+ </ul>
81
+
82
+ <h2 id="install">How to install the plugin</h2>
83
+
84
+ <ol>
85
+ <li>Uzip the <code>members.zip</code> folder.</li>
86
+ <li>Upload the <code>members</code> folder to your <code>/wp-content/plugins</code> directory.</li>
87
+ <li>In your WordPress dashboard, head over to the <em>Plugins</em> section.</li>
88
+ <li>Activate <em>Members</em>.</li>
89
+ </ol>
90
+
91
+ <h2 id="how-to">How to use the plugin</h2>
92
+
93
+ <p>This plugin is set up to have a components-based system. The reason for this is that I don't want to stick everyone with a bunch of features they don't need. There's no point in using the <em>Edit Roles</em> component if all you need is just a login widget and some shortcodes. So, it's a <em>use-only-what-you-want</em> system.</p>
94
+
95
+ <p>To add components, look for the <em>Members Components</em> link under your <em>Settings</em> menu while in your WordPress admin. When on the new page, you'll be able to select the components you want to use.</p>
96
+
97
+ <p>I recommend at least activating <em>Edit Roles</em> component. It is at the heart of this plugin, and many other components will likely require its use in some form.</p>
98
+
99
+ <h2 id="edit-roles">Edit Roles Component</h2>
100
+
101
+ <p>This component can be both a blessing and a curse, so I'm going to ask that you use it wisely. Use extreme caution when assigning new capabilities to roles. You wouldn't want to give Average Joe the <code>edit_plugins</code> capability, for example.</p>
102
+
103
+ <p><em>Edit Roles</em> is the big daddy of all the components. It allows you to edit and assign new capabilities to existing roles.</p>
104
+
105
+ <p>You can find the settings page for this component under the <em>Users</em> menu. It will be labeled <em>Roles</em>. When clicking on the menu item, you'll get a list of all the available roles. From there, you can select a role to edit.</p>
106
+
107
+ <p>To delete a role, you must have the <code>delete_roles</code> capability. If you don't have that, you won't see a delete option on the <em>Roles</em> page.</p>
108
+
109
+ <p class="alert">It is important that you assign the capability of <code>edit_roles</code> to a role (the administrator role would be a good one). That way, only users with that particular capability can edit roles.</p>
110
+
111
+ <h2 id="new-roles">New Roles Component</h2>
112
+
113
+ <p>The <em>New Roles</em> component allows you to create new roles. The menu item for this is located under the <em>Users</em> menu and is labeled <em>New Roles</em>.</p>
114
+
115
+ <p>You can only use this component (create new roles) if you have the <code>create_roles</code> capability. So, if you don't have that, you need to use the <em>Manage Roles</em> component to add that capability to the role you currently have.</p>
116
+
117
+ <p>Adding new roles is pretty straightforward. You need to input a <em>Role</em> (only use letters, numbers, and underscores), <em>Role Name</em>, and select which capabilities the new role should have. You can later manage this role using the <em>Edit Roles</em> component.</p>
118
+
119
+ <p>You can assign new roles to users from the <em>Authors &amp; Users</em> screen in WordPress. This is nothing particular to the plugin and is a default part of WordPress. I believe you need the <code>edit_users</code> capability to do this (I'll have to check).</p>
120
+
121
+ <h2 id="content-permissions">Content Permissions Component</h2>
122
+
123
+ <p>The <em>Content Permissions</em> component will be the heart and soul of this plugin in the future. Right now, it only adds an additional meta box on the post/page edit screen. This meta box allows you to select which roles can view the content of the post/page. If no roles are selected, anyone can view the content.</p>
124
+
125
+ <p>You need the <code>restrict_content</code> capability to use this component. So, you'll need to add this capability to your role using the <em>Edit Roles</em> component.</p>
126
+
127
+ <p class="alert">Note that you'll see a <em>Role</em> custom field key and values when testing this component. This is for my personal testing only right now.</p>
128
+
129
+ <h2 id="shortcodes">Shortcodes Component</h2>
130
+
131
+ <p>There are several shortcodes that you can use in your post/page editor. These need some major testing right now, so please offer any feedback you can.</p>
132
+
133
+ <h3 id="access">[access]</h3>
134
+
135
+ <p>The <code>[access]</code> shortcode is for hiding content from particular roles and capabilities. You need to wrap your content when using this shortcode:</p>
136
+
137
+ <pre><code>[access role="editor"]Hide this content from everyone but editors.[/access]</code></pre>
138
+
139
+ <p><strong>Parameters:</strong></p>
140
+
141
+ <ul>
142
+ <li><code>capability</code>: A capability that has been assigned to a role.</li>
143
+ <li><code>role</code>: A user role from WordPress or one that you've created.</li>
144
+ <li><code>feed</code>: Set to <code>true</code> if you'd like to show the content in feeds.</li>
145
+ </ul>
146
+
147
+ <p>Note that <code>capability</code> and <code>role</code> parameters aren't used in conjunction. The code first checks for the capability (if input) then checks for the role (if input).</p>
148
+
149
+ <h3 id="get-avatar">[get_avatar]</h3>
150
+
151
+ <p>This shortcode is for showing a user's avatar through <a href="http://gravatar.com" title="Gravatar">Gravatar</a>. It should be used like so within your post/page editor:</p>
152
+
153
+ <pre><code>[get_avatar id="30"]</code></pre>
154
+
155
+ <p><strong>Parameters:</strong></p>
156
+
157
+ <ul>
158
+ <li><code>id</code>: The ID of the user's avatar you'd like to show.</li>
159
+ <li><code>email</code>: The email of the user's avatar you'd like to show (you can use either <code>id</code> or <code>email</code></li>
160
+ <li><code>size</code>: The width and height in pixels of the avatar.</li>
161
+ <li><code>alt</code>: The <code>alt="Text"</code> that should appear for the image.</li>
162
+ <li><code>default</code>: A default image for users without a gravatar.</li>
163
+ </ul>
164
+
165
+ <h3 id="is-user-logged-in">[is_user_logged_in]</h3>
166
+
167
+ <p>The <code>[is_user_logged_in]</code> shortcode should be used to check if a user is currently logged into the site. If not, the content will be hidden.</p>
168
+
169
+ <pre><code>[is_user_logged_in]This content is only shown to logged-in users.[/is_user_logged_in]</code></pre>
170
+
171
+ <p>This shortcode has no parameters.</p>
172
+
173
+ <h3 id="feed">[feed]</h3>
174
+
175
+ <p>If you have content you only want to show to subscribers of your feed, wrap it in this shortcode:</p>
176
+
177
+ <pre><code>[feed]This content will only be shown in feeds.[/feed]</code></pre>
178
+
179
+ <p>This shortcode has no parameters.</p>
180
+
181
+ <h3 id="login-form">[login-form]</h3>
182
+
183
+ <p>The <code>[login-form]</code>shortcode produces a form for users to log into your site. More than likely, you'll want to use the <em>Login Form</em> widget for something like this. The shortcode should be used like so:</p>
184
+
185
+ <pre><code>[login-form]</code></pre>
186
+
187
+ <p>This shortcode has no parameters.</p>
188
+
189
+ <h2 id="template-tags">Template Tags Component</h2>
190
+
191
+ <p>The <em>Template Tags</em> component gives you additional functions (i.e., template tags) to use within your WordPress theme.</p>
192
+
193
+ <h3 id="current_user_has_role">current_user_has_role()</h3>
194
+
195
+ <p>This template tag checks if the currently logged-in user has a specific role.</p>
196
+
197
+ <pre><code>&lt;?php if ( function_exists( 'current_user_has_role' ) && current_user_has_role( 'editor' ) ) { ?>
198
+ Only users with the editor role can see this content.
199
+ &lt;?php } ?></code></pre>
200
+
201
+ <h3 id="has_role">has_role()</h3>
202
+
203
+ <p>This function will check if a specific user (by ID) has the given role.</p>
204
+
205
+ <pre><code>&lt;?php if ( function_exists( 'has_role' ) && has_role( 'editor', 30 ) ) { ?>
206
+ If the user with the ID or 30 has the editor role, this will be shown.
207
+ &lt;?php } ?></code></pre>
208
+
209
+ <h3 id="members_list_users">members_list_users()</h3>
210
+
211
+ <p>The <code>members_list_users()</code> template tag works much like <code>wp_list_authors()</code>. This is also a widget called <em>Users</em> if you're using the <em>Widgets</em> component.</p>
212
+
213
+ <pre><code>&lt;?php if ( function_exists( 'members_list_users' ) ) { ?>
214
+
215
+ &lt;ul>
216
+ &lt;?php members_list_users( array( 'order' => 'ASC', 'orderby' => 'display_name' ) ); ?>
217
+ &lt;/ul>
218
+
219
+ &lt;?php } ?></code></pre>
220
+
221
+ <p>This function currently only takes in a few parameters, but I hope to work more in sometime in the future.</p>
222
+
223
+ <ul>
224
+ <li><code>order</code>: Takes in <code>ASC</code> (ascending) or <code>DESC</code> (descending). The default is <code>ASC</code>.</li>
225
+ <li><code>orderby</code>: What to order your users by. The possible values are <code>display_name</code>, <code>ID</code>, and <code>user_login</code>. The default is <code>display_name</code>.</li>
226
+ <li><code>include</code>: Comma-separated list of user IDs to include in the list.</li>
227
+ <li><code>exclude</code>: Comma-separated list of user IDs to exclude from the list.</li>
228
+ <li><code>limit</code>: The number of users to show. Note that large lists can really hit the database.</li>
229
+ <li><code>show_fullname</code> This is set to <code>true</code> by default. If set to <code>false</code>, the users' display names will be shown.</li>
230
+ <li><code>echo</code>: Set to <code>false</code> to return the list of users rather than displaying them on screen.</li>
231
+ </ul>
232
+
233
+ <h3 id="members_author_profile">members_author_profile()</h3>
234
+
235
+ <p>A template tag to be used within The Loop for showing the current author's avatar, name (linked to author archive), and bio. A good place to use this is in your <code>single.php</code> template after the post.</p>
236
+
237
+ <pre><code>&lt;?php if ( function_exists( 'members_author_profile' ) ) members_author_profile(); ?></code></pre>
238
+
239
+ <h2 id="widgets">Widgets Component</h2>
240
+
241
+ <p>The widgets component provides easy-to-use widgets for your site. They can be used in any WordPress widget area (provided by your theme). Currently, there's the <em>Login Form</em> and <em>Users</em> widgets.</p>
242
+
243
+ <h3 id="login-widget">Login Form widget</h3>
244
+
245
+ <p>The <em>Login Form</em> gives you a login form. It's a mixture of a text widget and login form. It can also show your avatar.</p>
246
+
247
+ <p>It's pretty straightforward, but I'll provide more documentation later.</p>
248
+
249
+ <h3 id="users-widget">Users widget</h3>
250
+
251
+ <p>The <em>Users</em> widget allows you to list users in any widget area. It's based off the <code>members_list_users()</code> function, so all of the <a href="#members_list_users" title="members_list_users() template tag">parameters are the same</a>.</p>
252
+
253
+ <h2 id="private-blog">Private Blog Component</h2>
254
+
255
+ <p>The <em>Private Blog</em> component makes sure that only logged-in users can see anything on your site. If a user visits your site and is not logged in, they are immediately redirected to your <code>wp-login.php</code> (WordPress login) page.</p>
256
+
257
+ <p class="alert">Note that feeds are not currently blocked with this component, but it's likely they will be later with an introduction of a feeds component.</p>
258
+
259
+ <h2 id="capability-check">Checking if the current user has a capability</h2>
260
+
261
+ <p>In plugins and your theme template files, you might sometimes need to check if the currently logged in user has permission to do something. We do this by using the WordPress function <code>current_user_can()</code>. The basic format looks like this:</p>
262
+
263
+ <pre><code>&lt;?php if ( current_user_can( 'capability_name' ) ) echo 'This user can do something'; ?></code></pre>
264
+
265
+ <p>For a more practical situation, let's say you created a new capability called <code>read_pages</code>. Well, you might want to hide the content within your <code>page.php</code> template by adding this:</p>
266
+
267
+ <pre><code>&lt;?php if ( current_user_can( 'read_pages ' ) ) { ?>
268
+ &lt;?php the_content(); ?>
269
+ &lt;?php } ?></code></pre>
270
+
271
+ <p>Only users with a role that has the <code>read_pages</code> capability will be able to see the content.</p>
272
+
273
+ <h2 id="components-api">Components API</h2>
274
+
275
+ <p>The components API is for developing new components to use within the Members plugin. This API is meant to be used so that users can select which components they want to run. While it is possible to build something on top of the <em>Members</em> plugin without using the components API, this provides a way to jump start development and keep code clean and organized.</p>
276
+
277
+ <h3>Creating a custom component</h3>
278
+
279
+ <p>To create a custom component, you need to use the <code>register_members_component()</code> function in your plugin. You should wrap it within its own function.</p>
280
+
281
+ <pre><code>function register_my_components() {
282
+
283
+ register_members_component( array(
284
+ 'name' => 'component_name',
285
+ 'label' => __('Component Label', 'members'),
286
+ 'callback' => 'component_callback_function',
287
+ 'hook' => false,
288
+ 'description' => __('Add a description of your component.', 'members')
289
+ ) );
290
+ }</code></pre>
291
+
292
+ <ul>
293
+ <li><strong><em>Required</em></strong> <code>name</code>: A unique name for your component (do not localize this, use spaces, or hyphens).</li>
294
+ <li><strong><em>Required</em></strong> <code>label</code>: The name of the component that users will see (should be localized).</li>
295
+ <li><strong><em>Required</em></strong> <code>description</code>: The description of your plugin (should be localized).</li>
296
+ <li><strong><em>Optional</em></strong> <code>callback</code>: The function to call for your component.</li>
297
+ <li><strong><em>Optional</em></strong> <code>hook</code>: The action hook used to fire your callback function.</li>
298
+ </ul>
299
+
300
+ <p>Once you've done the above, you need to add your function to the <code>members_register_components</code> hook.</p>
301
+
302
+ <pre><code>add_action( 'members_register_components', 'register_my_components' );</code></pre>
303
+
304
+ <h3>Checking if a component is active</h3>
305
+
306
+ <p>If you want to check if a component is active (nice way to only load code if needed), you can use the <code>is_active_members_component()</code> function.</p>
307
+
308
+ <pre><code>if ( is_active_members_component( $component_name ) ) {
309
+ /* Load files or do something else. */
310
+ }</code></pre>
311
+
312
+ <h3>Getting a component</h3>
313
+
314
+ <p>If you need to grab a component object, you can do so with the <code>get_members_component()</code> function.</p>
315
+
316
+ <pre><code>$component = get_members_component( $component_name );
317
+
318
+ echo $component->name;
319
+ echo $component->label;
320
+ echo $component->description;
321
+ echo $component->callback;
322
+ echo $component->hook;</code></pre>
323
+
324
+ <h2 id="filter-caps">Adding new default capabilities</h2>
325
+
326
+ <p>Your plugin/theme can add new capabilities to the <em>Edit Roles</em> component if needed. This will allow users to easily select the additional capabilities for whichever roles they choose.</p>
327
+
328
+ <pre><code>add_filter( 'members_get_capabilities', 'my_plugin_new_caps' );
329
+
330
+ function my_plugin_new_caps( $capabilities ) {
331
+
332
+ $capabilities[] = 'cap_name_1';
333
+ $capabilities[] = 'cap_name_2';
334
+ $capabilities[] = 'cap_name_3';
335
+
336
+ return $capabilities;
337
+ }</code></pre>
338
+
339
+ <p>Note that you need to respect the existing capabilities and return the original array.</p>
340
+
341
+ <h2 id="cap-check">Checking for capabilities</h2>
342
+
343
+ <p>In WordPress, you can use the <code>current_user_can()</code> function to check if the current user has a particular capability. Since you don't know whether a user has this plugin installed, you might want to check first.</p>
344
+
345
+ <p>The <code>members_check_for_cap()</code> function (only use in admin) checks if any role has a particular capability. This can be useful in setting up something like admin menus. For example, you can set up a theme settings menu for users that have the <code>edit_themes</code> capability. But, if this plugin is installed and a user has the <code>edit_my_theme</code> capability, that'll be used instead.</p>
346
+
347
+ <pre><code>if ( function_exists( 'members_check_for_cap' ) && members_check_for_cap( 'some_cap' ) ) {
348
+ /* Do something if any role has the 'some_cap' capability. */
349
+ else {
350
+ /* Do something for people without the plugin. */
351
+ }</code></pre>
352
+
353
+ <h2 id="old-levels">Need the old user levels system?</h2>
354
+
355
+ <p>Some plugins and themes might rely on the old user level system in WordPress. WordPress still has legacy support for these, but I'm hoping to continue phasing out the use of them.</p>
356
+
357
+ <p>By default, the levels aren't shown. They still exist, but are tucked away behind the scenes. If you need to control who has what level (levels are just capabilities), add this to your plugin or your theme's <code>functions.php</code>:</p>
358
+
359
+ <pre><code>remove_filter( 'members_get_capabilities', 'members_remove_old_levels' );</code></pre>
360
+
361
+ <h2 id="plugin-support">Plugin support</h2>
362
+
363
+ <p>I run a WordPress community called <a href="http://themehybrid.com" title="Theme Hybrid">Theme Hybrid</a>, which is where I fully support all of my WordPress projects, including plugins. You can sign up for an account to get plugin support for a small yearly fee ($25 <acronym title="United States Dollars">USD</acronym> at the time of writing).</p>
364
+
365
+ <p>I know. I know. You might not want to pay for support, but just consider it a donation to the project. To continue making cool, <acronym title="GNU General Public License">GPL</acronym>-licensed plugins and having the time to support them, I must pay the bills.</p>
366
+
367
+ <h2 id="copyright">Copyright &amp; license</h2>
368
+
369
+ <p><em>Members</em> is licensed under the <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html" title="GNU GPL">GNU General Public License</a>, version 2 (<acronym title="GNU General Public License">GPL</acronym>).</p>
370
+
371
+ <p>This plugin is copyrighted to <a href="http://justintadlock.com" title="Justin Tadlock">Justin Tadlock</a>.</p>
372
+
373
+ <p>2009 &copy; Justin Tadlock</p>
374
+
375
+ </body>
376
+ </html>
readme.txt ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Members ===
2
+ Contributors: greenshady
3
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3687060
4
+ Tags: admin, cms, community, profile, shortcode, user, users
5
+ Requires at least: 2.8
6
+ Tested up to: 2.8.4
7
+ Stable tag: 0.1
8
+
9
+ A user, role, and content management plugin that makes WordPress a more powerful CMS.
10
+
11
+ == Description ==
12
+
13
+ *Members* is a plugin that extends your control over your blog. It's a user, role, and content management plugin that was created to make WordPress a more powerful CMS.
14
+
15
+ The plugin is created with a components-based system &mdash; you only have to use the features you want.
16
+
17
+ The foundation of the plugin is its extensive role and capability management system. This is the backbone of all the current features and planned future features.
18
+
19
+ **Components (i.e., features):**
20
+
21
+ * Edit Roles: Edit (and delete) specific roles and each role's capabilities.
22
+ * New Roles: Create new roles for use on your site.
23
+ * Content Permissions: Control what roles have access to specific posts and pages.
24
+ * Shortcodes: Use [shortcodes] to restrict/allow access to content.
25
+ * Template Tags: Functions to be used within your WordPress theme.
26
+ * Widgets: A login form and user list widget for use in any widget areas.
27
+ * Private Blog: Force visitors to log in before viewing your site.
28
+
29
+ == Installation ==
30
+
31
+ 1. Upload `members` to the `/wp-content/plugins/` directory.
32
+ 1. Activate the plugin through the 'Plugins' menu in WordPress.
33
+ 1. Go to <em>Settings > Members Components</em> to select which components you'd like to use.
34
+
35
+ More detailed instructions are included in the plugin's `readme.html` file.
36
+
37
+ == Frequently Asked Questions ==
38
+
39
+ = Why was this plugin created? =
40
+
41
+ I wasn't satisfied with the current user, role, and permissions plugins available. Yes, some of them are good, but nothing fit what I had in mind perfectly. Some offered few features. Some worked completely outside of the WordPress APIs. Others lacked the GPL license.
42
+
43
+ This plugin is still a long way away from my goals, but it'll get there eventually.
44
+
45
+ = How do I use it? =
46
+
47
+ Most things should be fairly straightforward, but I've included an in-depth guide in the plugin download. It's a file called `readme.html`.
48
+
49
+ You'll want to look over that. It's probably the most in-depth plugin documentation you'll ever read. ;)
50
+
51
+ == Changelog ==
52
+
53
+ **Version 0.1**
54
+
55
+ * Plugin launch. Everything's new!
settings.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The components settings page is an admin page that allows users to select which
4
+ * components of the plugin they wish to use.
5
+ *
6
+ * @package Members
7
+ */
8
+
9
+ /* Get the global $members object. */
10
+ global $members; ?>
11
+
12
+ <div class="wrap">
13
+
14
+ <h2><?php _e('Select Components', 'members'); ?></h2>
15
+
16
+ <?php do_action( 'members_pre_components_form' ); // Pre-form hook. Useful for things like messages once a component has been activated. ?>
17
+
18
+ <div id="poststuff">
19
+
20
+ <form method="post" action="options.php">
21
+
22
+ <?php settings_fields( 'members_plugin_settings' ); ?>
23
+ <?php $options = get_option( 'members_settings' ); ?>
24
+
25
+ <table id="all-plugins-table" class="widefat">
26
+
27
+ <thead>
28
+ <tr>
29
+ <th class='check-column'><input type='checkbox' /></th>
30
+ <th class='name-column'><?php _e('Component', 'members'); ?></th>
31
+ <th><?php _e('Description', 'members'); ?></th>
32
+ </tr>
33
+ </thead>
34
+
35
+ <tfoot>
36
+ <tr>
37
+ <th class='check-column'><input type='checkbox' /></th>
38
+ <th class='name-column'><?php _e('Component', 'members'); ?></th>
39
+ <th><?php _e('Description', 'members'); ?></th>
40
+ </tr>
41
+ </tfoot>
42
+
43
+ <?php if ( is_array( $members->registered_components ) ) { ?>
44
+
45
+ <tbody class="plugins">
46
+
47
+ <?php foreach ( $members->registered_components as $component ) { ?>
48
+
49
+ <?php if ( !$component->name ) continue; ?>
50
+
51
+ <tr valign="top" class="<?php if ( $options[$component->name] ) echo 'active'; else echo 'inactive'; ?>">
52
+
53
+ <th class="manage-column column-cb check-column">
54
+ <input type="checkbox" name="members_settings[<?php echo $component->name; ?>]" id="<?php echo $component->name; ?>" value="1" <?php checked( '1', $options[$component->name] ); ?> />
55
+ </th><!-- manage-column .column-cb .check-column -->
56
+
57
+ <td class="plugin-title">
58
+ <label for="<?php echo $component->name; ?>"><strong><?php echo $component->label; ?></strong></label>
59
+ </td><!-- .plugin-title -->
60
+
61
+ <td class="desc">
62
+ <p><?php echo $component->description; ?></p>
63
+ </td><!-- .desc -->
64
+
65
+ </tr><!-- .active/.inactive -->
66
+
67
+ <?php } // End loop through registered components. ?>
68
+
69
+ </tbody><!-- .plugins -->
70
+
71
+ <?php } // End check for registered components ?>
72
+
73
+ </table><!-- #all-plugins-table .widefat -->
74
+
75
+ <p class="submit">
76
+ <input type="submit" class="button-primary" value="<?php _e('Activate', 'members') ?>" />
77
+ </p><!-- .submit -->
78
+
79
+ </form>
80
+
81
+ </div><!-- #poststuff -->
82
+
83
+ </div><!-- .wrap -->