PluginProbe
Edit Flow / 0.7.5
Edit Flow v0.7.5
0.11.1 0.11.0 0.7.2 0.7.3 0.7.4 0.7.5 0.7.6 0.8 0.8.1 0.8.2 0.9 0.9.1 0.9.2 0.9.3 0.9.4 0.9.5 0.9.6 0.9.7 0.9.8 0.9.9 trunk 0.1.5 0.10.0 0.10.1 0.10.2 All 44 releases
edit-flow / modules / user-groups / user-groups.php

user-groups.php in Edit Flow 0.7.5, at modules/user-groups/user-groups.php

1,245 lines 45.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * class EF_User_Groups
4 *
5 * @todo all of them PHPdocs
6 * @todo Resolve whether the notifications component of this class should be moved to "subscriptions"
7 * @todo Decide whether it's functional to store user_ids in the term description array
8 * - Argument against: it's going to be expensive to look up usergroups for a user
9 *
10 */
11
12 if ( !class_exists( 'EF_User_Groups' ) ) {
13
14 class EF_User_Groups extends EF_Module {
15
16 var $module;
17
18 /**
19 * Keys for storing data
20 * - taxonomy_key - used for custom taxonomy
21 * - term_prefix - Used for custom taxonomy terms
22 */
23 const taxonomy_key = 'ef_usergroup';
24 const term_prefix = 'ef-usergroup-';
25
26 var $manage_usergroups_cap = 'edit_usergroups';
27
28 /**
29 * Register the module with Edit Flow but don't do anything else
30 *
31 * @since 0.7
32 */
33 function __construct( ) {
34 global $edit_flow;
35
36 $this->module_url = $this->get_module_url( __FILE__ );
37
38 // Register the User Groups module with Edit Flow
39 $args = array(
40 'title' => __( 'User Groups', 'edit-flow' ),
41 'short_description' => __( 'Organize your users into groups to mimic your organizational structure.', 'edit-flow' ),
42 'extended_description' => __( 'Configure user groups to organize all of the users on your site. Each user can be in many user groups and you can change them at any time.', 'edit-flow' ),
43 'module_url' => $this->module_url,
44 'img_url' => $this->module_url . 'lib/usergroups_s128.png',
45 'slug' => 'user-groups',
46 'default_options' => array(
47 'enabled' => 'on',
48 'post_types' => array(
49 'post' => 'on',
50 'page' => 'off',
51 ),
52 ),
53 'messages' => array(
54 'usergroup-added' => __( "User group created. Feel free to add users to the usergroup.", 'edit-flow' ),
55 'usergroup-updated' => __( "User group updated.", 'edit-flow' ),
56 'usergroup-missing' => __( "User group doesn't exist.", 'edit-flow' ),
57 'usergroup-deleted' => __( "User group deleted.", 'edit-flow' ),
58 ),
59 'configure_page_cb' => 'print_configure_view',
60 'configure_link_text' => __( 'Manage User Groups', 'edit-flow' ),
61 'autoload' => false,
62 'settings_help_tab' => array(
63 'id' => 'ef-user-groups-overview',
64 'title' => __('Overview', 'edit-flow'),
65 'content' => __('<p>For those with many people involved in the publishing process, user groups helps you keep them organized.</p><p>Currently, user groups are primarily used for subscribing a set of users to a post for notifications.</p>', 'edit-flow'),
66 ),
67 'settings_help_sidebar' => __( '<p><strong>For more information:</strong></p><p><a href="http://editflow.org/features/user-groups/">User Groups Documentation</a></p><p><a href="http://wordpress.org/tags/edit-flow?forum_id=10">Edit Flow Forum</a></p><p><a href="https://github.com/danielbachhuber/Edit-Flow">Edit Flow on Github</a></p>', 'edit-flow' ),
68 );
69 $this->module = EditFlow()->register_module( 'user_groups', $args );
70
71 }
72
73 /**
74 * Module startup
75 */
76
77 /**
78 * Initialize the rest of the stuff in the class if the module is active
79 *
80 * @since 0.7
81 */
82 function init() {
83
84 // Register the objects where we'll be storing data and relationships
85 $this->register_usergroup_objects();
86
87 $this->manage_usergroups_cap = apply_filters( 'ef_manage_usergroups_cap', $this->manage_usergroups_cap );
88
89 // Register our settings
90 add_action( 'admin_init', array( $this, 'register_settings' ) );
91
92 // Handle any adding, editing or saving
93 add_action( 'admin_init', array( $this, 'handle_add_usergroup' ) );
94 add_action( 'admin_init', array( $this, 'handle_edit_usergroup' ) );
95 add_action( 'admin_init', array( $this, 'handle_delete_usergroup' ) );
96 add_action( 'wp_ajax_inline_save_usergroup', array( $this, 'handle_ajax_inline_save_usergroup' ) );
97
98 // Usergroups can be managed from the User profile view
99 add_action( 'show_user_profile', array( $this, 'user_profile_page' ) );
100 add_action( 'edit_user_profile', array( $this, 'user_profile_page' ) );
101 add_action( 'user_profile_update_errors', array( $this, 'user_profile_update' ), 10, 3 );
102
103 // Javascript and CSS if we need it
104 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
105 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) );
106
107 }
108
109 /**
110 * Load the capabilities onto users the first time the module is run
111 *
112 * @since 0.7
113 */
114 function install() {
115
116 // Add necessary capabilities to allow management of user groups
117 $usergroup_roles = array(
118 'administrator' => array('edit_usergroups'),
119 );
120 foreach( $usergroup_roles as $role => $caps ) {
121 $this->add_caps_to_role( $role, $caps );
122 }
123
124 // Create our default usergroups
125 $default_usergroups = array(
126 array(
127 'name' => __( 'Copy Editors', 'edit-flow' ),
128 'description' => __( 'Making sure the quality is top-notch.', 'edit-flow' ),
129 ),
130 array(
131 'name' => __( 'Photographers', 'edit-flow' ),
132 'description' => __( 'Capturing the story visually.', 'edit-flow' ),
133 ),
134 array(
135 'name' => __( 'Reporters', 'edit-flow' ),
136 'description' => __( 'Out in the field, writing stories.', 'edit-flow' ),
137 ),
138 array(
139 'name' => __( 'Section Editors', 'edit-flow' ),
140 'description' => __( 'Providing feedback and direction.', 'edit-flow' ),
141 ),
142 );
143 foreach( $default_usergroups as $args ) {
144 $this->add_usergroup( $args );
145 }
146
147 }
148
149 /**
150 * Upgrade our data in case we need to
151 *
152 * @since 0.7
153 */
154 function upgrade( $previous_version ) {
155 global $edit_flow;
156
157 // Upgrade path to v0.7
158 if ( version_compare( $previous_version, '0.7' , '<' ) ) {
159 global $wpdb;
160
161 // Set all of the user group terms to our new taxonomy
162 $wpdb->update( $wpdb->term_taxonomy, array( 'taxonomy' => self::taxonomy_key ), array( 'taxonomy' => 'following_usergroups' ) );
163
164 // Get all of the users who are a part of user groups and assign them to their new user group values
165 $query = "SELECT * FROM $wpdb->usermeta WHERE meta_key='wp_ef_usergroups';";
166 $usergroup_users = $wpdb->get_results( $query );
167
168 // Sort all of the users based on their usergroup(s)
169 $users_to_add = array();
170 foreach( (array)$usergroup_users as $usergroup_user ) {
171 if ( is_object( $usergroup_user ) )
172 $users_to_add[$usergroup_user->meta_value][] = (int)$usergroup_user->user_id;
173 }
174 // Add user IDs to each usergroup
175 foreach( $users_to_add as $usergroup_slug => $users_array ) {
176 $usergroup = $this->get_usergroup_by( 'slug', $usergroup_slug );
177 $this->add_users_to_usergroup( $users_array, $usergroup->term_id );
178 }
179 // Update the term slugs for each user group
180 $all_usergroups = $this->get_usergroups();
181 foreach( $all_usergroups as $usergroup ) {
182 $new_slug = str_replace( 'ef_', self::term_prefix, $usergroup->slug );
183 $this->update_usergroup( $usergroup->term_id, array( 'slug' => $new_slug ) );
184 }
185
186 // Delete all of the previous usermeta values
187 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key='wp_ef_usergroups';" );
188
189 // Technically we've run this code before so we don't want to auto-install new data
190 $edit_flow->update_module_option( $this->module->name, 'loaded_once', true );
191
192 }
193 // Upgrade path to v0.7.4
194 if ( version_compare( $previous_version, '0.7.4', '<' ) ) {
195 // Usergroup descriptions become base64_encoded, instead of maybe json_encoded.
196 $this->upgrade_074_term_descriptions( self::taxonomy_key );
197 }
198
199 }
200
201 /**
202 * Individual Usergroups are stored using a custom taxonomy
203 * Posts are associated with usergroups based on taxonomy relationship
204 * User associations are stored serialized in the term's description field
205 *
206 * @since 0.7
207 *
208 * @uses register_taxonomy()
209 */
210 function register_usergroup_objects() {
211
212 // Load the currently supported post types so we only register against those
213 $supported_post_types = $this->get_post_types_for_module( $this->module );
214
215 // Use a taxonomy to manage relationships between posts and usergroups
216 $args = array(
217 'public' => false,
218 'rewrite' => false,
219 );
220 register_taxonomy( self::taxonomy_key, $supported_post_types, $args );
221 }
222
223 /**
224 * Enqueue necessary admin scripts
225 *
226 * @since 0.7
227 *
228 * @uses wp_enqueue_script()
229 */
230 function enqueue_admin_scripts() {
231
232 if ( $this->is_whitelisted_functional_view() || $this->is_whitelisted_settings_view( $this->module->name ) ) {
233 wp_enqueue_script( 'jquery-listfilterizer' );
234 wp_enqueue_script( 'jquery-quicksearch' );
235 wp_enqueue_script( 'edit-flow-user-groups-js', $this->module_url . 'lib/user-groups.js', array( 'jquery', 'jquery-listfilterizer', 'jquery-quicksearch' ), EDIT_FLOW_VERSION, true );
236 }
237
238 if ( $this->is_whitelisted_settings_view( $this->module->name ) )
239 wp_enqueue_script( 'edit-flow-user-groups-configure-js', $this->module_url . 'lib/user-groups-configure.js', array( 'jquery' ), EDIT_FLOW_VERSION, true );
240 }
241
242 /**
243 * Enqueue necessary admin styles, but only on the proper pages
244 *
245 * @since 0.7
246 *
247 * @uses wp_enqueue_style()
248 */
249 function enqueue_admin_styles() {
250
251
252 if ( $this->is_whitelisted_functional_view() || $this->is_whitelisted_settings_view() ) {
253 wp_enqueue_style( 'jquery-listfilterizer' );
254 wp_enqueue_style( 'edit-flow-user-groups-css', $this->module_url . 'lib/user-groups.css', false, EDIT_FLOW_VERSION );
255 }
256 }
257
258 /**
259 * Module ???
260 */
261
262 /**
263 * Handles a POST request to add a new Usergroup. Redirects to edit view after
264 * for admin to add users to usergroup
265 * Hooked into 'admin_init' and kicks out right away if no action
266 *
267 * @since 0.7
268 */
269 function handle_add_usergroup() {
270
271 if ( !isset( $_POST['submit'], $_POST['form-action'], $_GET['page'] )
272 || $_GET['page'] != $this->module->settings_slug || $_POST['form-action'] != 'add-usergroup' )
273 return;
274
275 if ( !wp_verify_nonce( $_POST['_wpnonce'], 'add-usergroup' ) )
276 wp_die( $this->module->messages['nonce-failed'] );
277
278 if ( !current_user_can( $this->manage_usergroups_cap ) )
279 wp_die( $this->module->messages['invalid-permissions'] );
280
281 // Sanitize all of the user-entered values
282 $name = strip_tags( trim( $_POST['name'] ) );
283 $description = strip_tags( trim( $_POST['description'] ) );
284
285 $_REQUEST['form-errors'] = array();
286
287 /**
288 * Form validation for adding new Usergroup
289 *
290 * Details
291 * - 'name' is a required field, but can't match an existing name or slug. Needs to be 40 characters or less
292 * - "description" can accept a limited amount of HTML, and is optional
293 */
294 // Field is required
295 if ( empty( $name ) )
296 $_REQUEST['form-errors']['name'] = __( 'Please enter a name for the user group.', 'edit-flow' );
297 // Check to ensure a term with the same name doesn't exist
298 if ( $this->get_usergroup_by( 'name', $name ) )
299 $_REQUEST['form-errors']['name'] = __( 'Name already in use. Please choose another.', 'edit-flow' );
300 // Check to ensure a term with the same slug doesn't exist
301 if ( $this->get_usergroup_by( 'slug', sanitize_title( $name ) ) )
302 $_REQUEST['form-errors']['name'] = __( 'Name conflicts with slug for another term. Please choose again.', 'edit-flow' );
303 if ( strlen( $name ) > 40 )
304 $_REQUEST['form-errors']['name'] = __( 'User group name cannot exceed 40 characters. Please try a shorter name.', 'edit-flow' );
305 // Kick out if there are any errors
306 if ( count( $_REQUEST['form-errors'] ) ) {
307 $_REQUEST['error'] = 'form-error';
308 return;
309 }
310
311 // Try to add the Usergroup
312 $args = array(
313 'name' => $name,
314 'description' => $description,
315 );
316 $usergroup = $this->add_usergroup( $args );
317 if ( is_wp_error( $usergroup ) )
318 wp_die( __( 'Error adding usergroup.', 'edit-flow' ) );
319
320 $args = array(
321 'action' => 'edit-usergroup',
322 'usergroup-id' => $usergroup->term_id,
323 'message' => 'usergroup-added'
324 );
325 $redirect_url = $this->get_link( $args );
326 wp_redirect( $redirect_url );
327 exit;
328 }
329
330 /**
331 * Handles a POST request to edit a Usergroup
332 * Hooked into 'admin_init' and kicks out right away if no action
333 *
334 * @since 0.7
335 */
336 function handle_edit_usergroup() {
337 if ( !isset( $_POST['submit'], $_POST['form-action'], $_GET['page'] )
338 || $_GET['page'] != $this->module->settings_slug || $_POST['form-action'] != 'edit-usergroup' )
339 return;
340
341 if ( !wp_verify_nonce( $_POST['_wpnonce'], 'edit-usergroup' ) )
342 wp_die( $this->module->messages['nonce-failed'] );
343
344 if ( !current_user_can( $this->manage_usergroups_cap ) )
345 wp_die( $this->module->messages['invalid-permissions'] );
346
347 if ( !$existing_usergroup = $this->get_usergroup_by( 'id', (int)$_POST['usergroup_id'] ) )
348 wp_die( $this->module->messsage['usergroup-error'] );
349
350 // Sanitize all of the user-entered values
351 $name = strip_tags( trim( $_POST['name'] ) );
352 $description = strip_tags( trim( $_POST['description'] ) );
353
354 $_REQUEST['form-errors'] = array();
355
356 /**
357 * Form validation for editing a Usergroup
358 *
359 * Details
360 * - 'name' is a required field, but can't match an existing name or slug. Needs to be 40 characters or less
361 * - "description" can accept a limited amount of HTML, and is optional
362 */
363 // Field is required
364 if ( empty( $name ) )
365 $_REQUEST['form-errors']['name'] = __( 'Please enter a name for the user group.', 'edit-flow' );
366 // Check to ensure a term with the same name doesn't exist
367 $search_term = $this->get_usergroup_by( 'name', $name );
368 if ( is_object( $search_term ) && $search_term->term_id != $existing_usergroup->term_id )
369 $_REQUEST['form-errors']['name'] = __( 'Name already in use. Please choose another.', 'edit-flow' );
370 // Check to ensure a term with the same slug doesn't exist
371 $search_term = $this->get_usergroup_by( 'slug', sanitize_title( $name ) );
372 if ( is_object( $search_term ) && $search_term->term_id != $existing_usergroup->term_id )
373 $_REQUEST['form-errors']['name'] = __( 'Name conflicts with slug for another term. Please choose again.', 'edit-flow' );
374 if ( strlen( $name ) > 40 )
375 $_REQUEST['form-errors']['name'] = __( 'User group name cannot exceed 40 characters. Please try a shorter name.', 'edit-flow' );
376 // Kick out if there are any errors
377 if ( count( $_REQUEST['form-errors'] ) ) {
378 $_REQUEST['error'] = 'form-error';
379 return;
380 }
381
382 // Try to edit the Usergroup
383 $args = array(
384 'name' => $name,
385 'description' => $description,
386 );
387 // Gracefully handle the case where all users have been unsubscribed from the user group
388 $users = isset( $_POST['usergroup_users'] ) ? (array)$_POST['usergroup_users'] : array();
389 $users = array_map( 'intval', $users );
390 $usergroup = $this->update_usergroup( $existing_usergroup->term_id, $args, $users );
391 if ( is_wp_error( $usergroup ) )
392 wp_die( __( 'Error updating user group.', 'edit-flow' ) );
393
394 $args = array(
395 'message' => 'usergroup-updated',
396 );
397 $redirect_url = $this->get_link( $args );
398 wp_redirect( $redirect_url );
399 exit;
400 }
401
402 /**
403 * Handles a request to delete a Usergroup.
404 * Hooked into 'admin_init' and kicks out right away if no action
405 *
406 * @since 0.7
407 */
408 function handle_delete_usergroup() {
409 if ( !isset( $_GET['page'], $_GET['action'], $_GET['usergroup-id'] )
410 || $_GET['page'] != $this->module->settings_slug || $_GET['action'] != 'delete-usergroup' )
411 return;
412
413 if ( !wp_verify_nonce( $_GET['nonce'], 'delete-usergroup' ) )
414 wp_die( $this->module->messages['nonce-failed'] );
415
416 if ( !current_user_can( $this->manage_usergroups_cap ) )
417 wp_die( $this->module->messages['invalid-permissions'] );
418
419 $result = $this->delete_usergroup( (int)$_GET['usergroup-id'] );
420 if ( !$result || is_wp_error( $result ) )
421 wp_die( __( 'Error deleting user group.', 'edit-flow' ) );
422
423 $redirect_url = $this->get_link( array( 'message' => 'usergroup-deleted' ) );
424 wp_redirect( $redirect_url );
425 exit;
426 }
427
428 /**
429 * Handle the request to update a given Usergroup via inline edit
430 *
431 * @since 0.7
432 */
433 function handle_ajax_inline_save_usergroup() {
434
435 if ( !wp_verify_nonce( $_POST['inline_edit'], 'usergroups-inline-edit-nonce' ) )
436 die( $this->module->messages['nonce-failed'] );
437
438 if ( !current_user_can( $this->manage_usergroups_cap ) )
439 die( $this->module->messages['invalid-permissions'] );
440
441 $usergroup_id = (int) $_POST['usergroup_id'];
442 if ( !$existing_term = $this->get_usergroup_by( 'id', $usergroup_id ) )
443 die( $this->module->messsage['usergroup-error'] );
444
445 $name = strip_tags( trim( $_POST['name'] ) );
446 $description = strip_tags( trim( $_POST['description'] ) );
447
448 /**
449 * Form validation for editing Usergroup
450 */
451 // Check if name field was filled in
452 if ( empty( $name ) ) {
453 $change_error = new WP_Error( 'invalid', __( 'Please enter a name for the user group.', 'edit-flow' ) );
454 die( $change_error->get_error_message() );
455 }
456 // Check that the name doesn't exceed 40 chars
457 if ( strlen( $name ) > 40 ) {
458 $change_error = new WP_Error( 'invalid', __( 'User group name cannot exceed 40 characters. Please try a shorter name.' ) );
459 die( $change_error->get_error_message() );
460 }
461 // Check to ensure a term with the same name doesn't exist
462 $search_term = $this->get_usergroup_by( 'name', $name );
463 if ( is_object( $search_term ) && $search_term->term_id != $existing_term->term_id ) {
464 $change_error = new WP_Error( 'invalid', __( 'Name already in use. Please choose another.', 'edit-flow' ) );
465 die( $change_error->get_error_message() );
466 }
467 // Check to ensure a term with the same slug doesn't exist
468 $search_term = $this->get_usergroup_by( 'slug', sanitize_title( $name ) );
469 if ( is_object( $search_term ) && $search_term->term_id != $existing_term->term_id ) {
470 $change_error = new WP_Error( 'invalid', __( 'Name conflicts with slug for another term. Please choose again.', 'edit-flow' ) );
471 die( $change_error->get_error_message() );
472 }
473
474 // Prepare the term name and description for saving
475 $args = array(
476 'name' => $name,
477 'description' => $description,
478 );
479 $return = $this->update_usergroup( $existing_term->term_id, $args );
480 if( !is_wp_error( $return ) ) {
481 set_current_screen( 'edit-usergroup' );
482 $wp_list_table = new EF_Usergroups_List_Table();
483 $wp_list_table->prepare_items();
484 echo $wp_list_table->single_row( $return );
485 die();
486 } else {
487 $change_error = new WP_Error( 'invalid', sprintf( __( 'Could not update the user group: <strong>%s</strong>', 'edit-flow' ), $usergroup_name ) );
488 die( $change_error->get_error_message() );
489 }
490
491 }
492
493 /**
494 * Register settings for notifications so we can partially use the Settings API
495 * (We use the Settings API for form generation, but not saving)
496 *
497 * @since 0.7
498 * @uses add_settings_section(), add_settings_field()
499 */
500 function register_settings() {
501 add_settings_section( $this->module->options_group_name . '_general', false, '__return_false', $this->module->options_group_name );
502 add_settings_field( 'post_types', __( 'Add to these post types:', 'edit-flow' ), array( $this, 'settings_post_types_option' ), $this->module->options_group_name, $this->module->options_group_name . '_general' );
503 }
504
505 /**
506 * Choose the post types for Usergroups
507 *
508 * @since 0.7
509 */
510 function settings_post_types_option() {
511 global $edit_flow;
512 $edit_flow->settings->helper_option_custom_post_type( $this->module );
513 }
514
515 /**
516 * Validate data entered by the user
517 *
518 * @since 0.7
519 *
520 * @param array $new_options New values that have been entered by the user
521 * @return array $new_options Form values after they've been sanitized
522 */
523 function settings_validate( $new_options ) {
524
525
526 // Whitelist validation for the post type options
527 if ( !isset( $new_options['post_types'] ) )
528 $new_options['post_types'] = array();
529 $new_options['post_types'] = $this->clean_post_type_options( $new_options['post_types'], $this->module->post_type_support );
530
531 return $new_options;
532 }
533
534 /**
535 * Build a configuration view so we can manage our usergroups
536 *
537 * @since 0.7
538 */
539 function print_configure_view() {
540 global $edit_flow;
541
542 if ( isset( $_GET['action'], $_GET['usergroup-id'] ) && $_GET['action'] == 'edit-usergroup' ) :
543 /** Full page width view for editing a given usergroup **/
544 // Check whether the usergroup exists
545 $usergroup_id = (int)$_GET['usergroup-id'];
546 $usergroup = $this->get_usergroup_by( 'id', $usergroup_id );
547 if ( !$usergroup ) {
548 echo '<div class="error"><p>' . $this->module->messages['usergroup-missing'] . '</p></div>';
549 return;
550 }
551 $name = ( isset( $_POST['name'] ) ) ? stripslashes( $_POST['name'] ) : $usergroup->name;
552 $description = ( isset( $_POST['description'] ) ) ? stripslashes( $_POST['description'] ) : $usergroup->description;
553 ?>
554 <form method="post" action="<?php echo esc_url( $this->get_link( array( 'action' => 'edit-usergroup', 'usergroup-id' => $usergroup_id ) ) ); ?>">
555 <div id="col-right"><div class="col-wrap"><div id="ef-usergroup-users" class="form-wrap">
556 <h4><?php _e( 'Users', 'edit-flow' ); ?></h4>
557 <?php
558 $select_form_args = array(
559 'list_class' => 'ef-post_following_list',
560 'input_id' => 'usergroup_users'
561 );
562 ?>
563 <?php $this->users_select_form( $usergroup->user_ids , $select_form_args ); ?>
564 </div></div></div>
565 <div id="col-left"><div class="col-wrap"><div class="form-wrap">
566 <input type="hidden" name="form-action" value="edit-usergroup" />
567 <input type="hidden" name="usergroup_id" value="<?php echo esc_attr( $usergroup_id ); ?>" />
568 <?php
569 wp_original_referer_field();
570 wp_nonce_field( 'edit-usergroup' );
571 ?>
572 <div class="form-field form-required">
573 <label for="name"><?php _e( 'Name', 'edit-flow' ); ?></label>
574 <input name="name" id="name" type="text" value="<?php echo esc_attr( $name ); ?>" size="40" maxlength="40" aria-required="true" />
575 <?php $edit_flow->settings->helper_print_error_or_description( 'name', __( 'The name is used to identify the user group.', 'edit-flow' ) ); ?>
576 </div>
577 <div class="form-field">
578 <label for="description"><?php _e( 'Description', 'edit-flow' ); ?></label>
579 <textarea name="description" id="description" rows="5" cols="40"><?php echo esc_html( $description ); ?></textarea>
580 <?php $edit_flow->settings->helper_print_error_or_description( 'description', __( 'The description is primarily for administrative use, to give you some context on what the user group is to be used for.', 'edit-flow' ) ); ?>
581 </div>
582 <p class="submit">
583 <?php submit_button( __( 'Update User Group', 'edit-flow' ), 'primary', 'submit', false ); ?>
584 <a class="cancel-settings-link" href="<?php echo esc_url( $this->get_link() ); ?>"><?php _e( 'Cancel', 'edit-flow' ); ?></a>
585 </p>
586 </div></div></div>
587 </form>
588
589 <?php else :
590 /** Full page width view to allow adding a usergroup and edit the existing ones **/
591 $wp_list_table = new EF_Usergroups_List_Table();
592 $wp_list_table->prepare_items();
593 ?>
594 <script type="text/javascript">
595 var ef_confirm_delete_usergroup_string = "<?php _e( 'Are you sure you want to delete the user group?', 'edit-flow' ); ?>";
596 </script>
597 <div id="col-right"><div class="col-wrap">
598 <?php $wp_list_table->display(); ?>
599 </div></div>
600 <div id="col-left"><div class="col-wrap"><div class="form-wrap">
601 <h3 class="nav-tab-wrapper">
602 <a href="<?php echo esc_url( $this->get_link() ); ?>" class="nav-tab<?php if ( !isset( $_GET['action'] ) || $_GET['action'] != 'change-options' ) echo ' nav-tab-active'; ?>"><?php _e( 'Add New', 'edit-flow' ); ?></a>
603 <a href="<?php echo esc_url( $this->get_link( array( 'action' => 'change-options' ) ) ); ?>" class="nav-tab<?php if ( isset( $_GET['action'] ) && $_GET['action'] == 'change-options' ) echo ' nav-tab-active'; ?>"><?php _e( 'Options', 'edit-flow' ); ?></a>
604 </h3>
605 <?php if ( isset( $_GET['action'] ) && $_GET['action'] == 'change-options' ): ?>
606 <form class="basic-settings" action="<?php echo esc_url( $this->get_link( array( 'action' => 'change-options' ) ) ); ?>" method="post">
607 <?php settings_fields( $this->module->options_group_name ); ?>
608 <?php do_settings_sections( $this->module->options_group_name ); ?>
609 <?php echo '<input id="edit_flow_module_name" name="edit_flow_module_name" type="hidden" value="' . esc_attr( $this->module->name ) . '" />'; ?>
610 <?php submit_button(); ?>
611 </form>
612 <?php else: ?>
613 <?php /** Custom form for adding a new Usergroup **/ ?>
614 <form class="add:the-list:" action="<?php echo esc_url( $this->get_link() ); ?>" method="post" id="addusergroup" name="addusergroup">
615 <div class="form-field form-required">
616 <label for="name"><?php _e( 'Name', 'edit-flow' ); ?></label>
617 <input type="text" aria-required="true" id="name" name="name" maxlength="40" value="<?php if ( !empty( $_POST['name'] ) ) echo esc_attr( $_POST['name'] ); ?>" />
618 <?php $edit_flow->settings->helper_print_error_or_description( 'name', __( 'The name is used to identify the user group.', 'edit-flow' ) ); ?>
619 </div>
620 <div class="form-field">
621 <label for="description"><?php _e( 'Description', 'edit-flow' ); ?></label>
622 <textarea cols="40" rows="5" id="description" name="description"><?php if ( !empty( $_POST['description'] ) ) echo esc_html( $_POST['description'] ) ?></textarea>
623 <?php $edit_flow->settings->helper_print_error_or_description( 'description', __( 'The description is primarily for administrative use, to give you some context on what the user group is to be used for.', 'edit-flow' ) ); ?>
624 </div>
625 <?php wp_nonce_field( 'add-usergroup' ); ?>
626 <?php echo '<input id="form-action" name="form-action" type="hidden" value="add-usergroup" />'; ?>
627 <p class="submit"><?php submit_button( __( 'Add New User Group', 'edit-flow' ), 'primary', 'submit', false ); ?><a class="cancel-settings-link" href="<?php echo EDIT_FLOW_SETTINGS_PAGE; ?>"><?php _e( 'Back to Edit Flow', 'edit-flow' ); ?></a></p>
628 </form>
629 <?php endif; ?>
630 </div></div></div>
631 <?php $wp_list_table->inline_edit(); ?>
632 <?php endif;
633 }
634
635 /**
636 * Adds a form to the user profile page to allow adding usergroup selecting options
637 */
638 function user_profile_page() {
639 global $user_id, $profileuser;
640
641 if ( !$user_id || !current_user_can( $this->manage_usergroups_cap ) )
642 return;
643
644 // Assemble all necessary data
645 $usergroups = $this->get_usergroups();
646 $selected_usergroups = $this->get_usergroups_for_user( $user_id );
647 $usergroups_form_args = array( 'input_id' => 'ef_usergroups' );
648 ?>
649 <table id="ef-user-usergroups" class="form-table"><tbody><tr>
650 <th>
651 <h3><?php _e( 'Usergroups', 'edit-flow' ) ?></h3>
652 <?php if ( $user_id === wp_get_current_user()->ID ) : ?>
653 <p><?php _e( 'Select the user groups that you would like to be a part of:', 'edit-flow' ) ?></p>
654 <?php else : ?>
655 <p><?php _e( 'Select the user groups that this user should be a part of:', 'edit-flow' ) ?></p>
656 <?php endif; ?>
657 </th>
658 <td>
659 <?php $this->usergroups_select_form( $selected_usergroups, $usergroups_form_args ); ?>
660 <script type="text/javascript">
661 jQuery(document).ready(function(){
662 jQuery('#ef-user-usergroups ul').listFilterizer();
663 });
664 </script>
665 </td>
666 </tr></tbody></table>
667 <?php wp_nonce_field( 'ef_edit_profile_usergroups_nonce', 'ef_edit_profile_usergroups_nonce' ); ?>
668 <?php
669 }
670
671 /**
672 * Function called when a user's profile is updated
673 * Adds user to specified usergroups
674 *
675 * @since 0.7
676 *
677 * @param ???
678 * @param ???
679 * @param ???
680 * @return ???
681 */
682 function user_profile_update( $errors, $update, $user ) {
683
684 if ( !$update )
685 return array( &$errors, $update, &$user );
686
687 if ( current_user_can( $this->manage_usergroups_cap ) && wp_verify_nonce( $_POST['ef_edit_profile_usergroups_nonce'], 'ef_edit_profile_usergroups_nonce' ) ) {
688 // Sanitize the data and save
689 // Gracefully handle the case where the user was unsubscribed from all usergroups
690 $usergroups = isset( $_POST['ef_usergroups'] ) ? array_map( 'intval', (array)$_POST['ef_usergroups'] ) : array();
691 $all_usergroups = $this->get_usergroups();
692 foreach( $all_usergroups as $usergroup ) {
693 if ( in_array( $usergroup->term_id, $usergroups ) )
694 $this->add_user_to_usergroup( $user->ID, $usergroup->term_id );
695 else
696 $this->remove_user_from_usergroup( $user->ID, $usergroup->term_id );
697 }
698 }
699
700 return array( &$errors, $update, &$user );
701 }
702
703 /**
704 * Generate a link to one of the usergroups actions
705 *
706 * @since 0.7
707 *
708 * @param string $action Action we want the user to take
709 * @param array $args Any query args to add to the URL
710 * @return string $link Direct link to delete a usergroup
711 */
712 function get_link( $args = array() ) {
713 if ( !isset( $args['action'] ) )
714 $args['action'] = '';
715 if ( !isset( $args['page'] ) )
716 $args['page'] = $this->module->settings_slug;
717 // Add other things we may need depending on the action
718 switch( $args['action'] ) {
719 case 'delete-usergroup':
720 $args['nonce'] = wp_create_nonce( $args['action'] );
721 break;
722 default:
723 break;
724 }
725 return add_query_arg( $args, get_admin_url( null, 'admin.php' ) );
726 }
727
728 /**
729 * Displays a list of usergroups with checkboxes
730 *
731 * @since 0.7
732 *
733 * @param array $selected List of usergroup keys that should be checked
734 * @param array $args ???
735 */
736 function usergroups_select_form( $selected = array(), $args = null ) {
737
738 // TODO add $args for additional options
739 // e.g. showing members assigned to group (John Smith, Jane Doe, and 9 others)
740 // before <tag>, after <tag>, class, id names?
741 $defaults = array(
742 'list_class' => 'ef-post_following_list',
743 'list_id' => 'ef-following_usergroups',
744 'input_id' => 'following_usergroups'
745 );
746
747 $parsed_args = wp_parse_args( $args, $defaults );
748 extract( $parsed_args, EXTR_SKIP );
749 $usergroups = $this->get_usergroups();
750 if ( empty($usergroups) ) {
751 ?>
752 <p><?php _e('No user groups were found.', 'edit-flow') ?> <a href="<?php echo esc_url( $this->get_link() ); ?>" title="<?php _e('Add a new user group. Opens new window.', 'edit-flow' ) ?>" target="_blank"><?php _e( 'Add a User Group', 'edit-flow' ); ?></a></p>
753 <?php
754 } else {
755
756 ?>
757 <ul id="<?php echo $list_id ?>" class="<?php echo $list_class ?>">
758 <?php
759 foreach( $usergroups as $usergroup ) {
760 $checked = ( in_array( $usergroup->term_id, $selected ) ) ? ' checked="checked"' : '';
761 ?>
762 <li>
763 <label for="<?php echo $input_id . esc_attr( $usergroup->term_id ); ?>" title="<?php echo esc_attr($usergroup->description) ?>">
764 <input type="checkbox" id="<?php echo $input_id . esc_attr( $usergroup->term_id ) ?>" name="<?php echo $input_id ?>[]" value="<?php echo esc_attr( $usergroup->term_id ) ?>"<?php echo $checked ?> />
765 <span class="ef-usergroup_name"><?php echo esc_html( $usergroup->name ); ?></span>
766 <span class="ef-usergroup_description" title="<?php echo esc_attr($usergroup->description) ?>">
767 <?php echo (strlen($usergroup->description) >= 50) ? substr_replace(esc_html($usergroup->description), '...', 50) : esc_html($usergroup->description); ?>
768 </span>
769 </label>
770 </li>
771 <?php
772 }
773 ?>
774 </ul>
775 <?php
776 }
777 }
778
779 /**
780 * Core Usergroups Module Functionality
781 */
782
783 /**
784 * Get all of the registered usergroups. Returns an array of objects
785 *
786 * @since 0.7
787 *
788 * @param array $args Arguments to filter/sort by
789 * @return array|bool $usergroups Array of Usergroups with relevant data, false if none
790 */
791 function get_usergroups( $args = array() ) {
792
793 // We want empty terms by default
794 if ( !isset( $args['hide_empty'] ) )
795 $args['hide_empty'] = 0;
796
797 $usergroup_terms = get_terms( self::taxonomy_key, $args );
798 if ( !$usergroup_terms )
799 return false;
800
801 // Run the usergroups through get_usergroup_by() so we load users too
802 $usergroups = array();
803 foreach( $usergroup_terms as $usergroup_term ) {
804 $usergroups[] = $this->get_usergroup_by( 'id', $usergroup_term->term_id );
805 }
806 return $usergroups;
807 }
808
809 /**
810 * Get all of the data associated with a single usergroup
811 * Usergroup contains:
812 * - ID (key = term_id)
813 * - Slug (prefixed with our special key to avoid conflicts)
814 * - Name
815 * - Description
816 * - User IDs (array of IDs)
817 *
818 * @since 0.7
819 *
820 * @param string $field 'id', 'name', or 'slug'
821 * @param int|string $value Value for the search field
822 * @return object|array|WP_Error $usergroup Usergroup information as specified by $output
823 */
824 function get_usergroup_by( $field, $value ) {
825
826 $usergroup = get_term_by( $field, $value, self::taxonomy_key );
827
828 if ( !$usergroup || is_wp_error( $usergroup ) )
829 return $usergroup;
830
831 // We're using an encoded description field to store extra values
832 // Declare $user_ids ahead of time just in case it's empty
833 $usergroup->user_ids = array();
834 $unencoded_description = $this->get_unencoded_description( $usergroup->description );
835 if ( is_array( $unencoded_description ) ) {
836 foreach( $unencoded_description as $key => $value ) {
837 $usergroup->$key = $value;
838 }
839 }
840 return $usergroup;
841 }
842
843 /**
844 * Create a new usergroup containing:
845 * - Name
846 * - Slug (prefixed with our special key to avoid conflicts)
847 * - Description
848 * - Users
849 *
850 * @since 0.7
851 *
852 * @param array $args Name (optional), slug and description for the usergroup
853 * @param array $user_ids IDs for the users to be added to the Usergroup
854 * @return object|WP_Error $usergroup Object for the new Usergroup on success, WP_Error otherwise
855 */
856 function add_usergroup( $args = array(), $user_ids = array() ) {
857
858 if ( !isset( $args['name'] ) )
859 return new WP_Error( 'invalid', __( 'New user groups must have a name', 'edit-flow' ) );
860
861 $name = $args['name'];
862 $default = array(
863 'name' => '',
864 'slug' => self::term_prefix . sanitize_title( $name ),
865 'description' => '',
866 );
867 $args = array_merge( $default, $args );
868
869 // Encode our extra fields and then store them in the description field
870 $args_to_encode = array(
871 'description' => $args['description'],
872 'user_ids' => array_unique( $user_ids ),
873 );
874 $encoded_description = $this->get_encoded_description( $args_to_encode );
875 $args['description'] = $encoded_description;
876 $usergroup = wp_insert_term( $name, self::taxonomy_key, $args );
877 if ( is_wp_error( $usergroup ) )
878 return $usergroup;
879
880 return $this->get_usergroup_by( 'id', $usergroup['term_id'] );
881 }
882
883 /**
884 * Update a usergroup with new data.
885 * Fields can include:
886 * - Name
887 * - Slug (prefixed with our special key, of course)
888 * - Description
889 * - Users
890 *
891 * @since 0.7
892 *
893 * @param int $id Unique ID for the usergroup
894 * @param array $args Usergroup meta to update (name, slug, description)
895 * @param array $users Users to be added to the Usergroup. If set, removes existing users first.
896 * @return object|WP_Error $usergroup Object for the updated Usergroup on success, WP_Error otherwise
897 */
898 function update_usergroup( $id, $args = array(), $users = null ) {
899
900 $existing_usergroup = $this->get_usergroup_by( 'id', $id );
901 if ( is_wp_error( $existing_usergroup ) )
902 return new WP_Error( 'invalid', __( "User group doesn't exist.", 'edit-flow' ) );
903
904 // Encode our extra fields and then store them in the description field
905 $args_to_encode = array();
906 $args_to_encode['description'] = ( isset( $args['description'] ) ) ? $args['description'] : $existing_usergroup->description;
907 $args_to_encode['user_ids'] = ( is_array( $users ) ) ? $users : $existing_usergroup->user_ids;
908 $args_to_encode['user_ids'] = array_unique( $args_to_encode['user_ids'] );
909 $encoded_description = $this->get_encoded_description( $args_to_encode );
910 $args['description'] = $encoded_description;
911
912 $usergroup = wp_update_term( $id, self::taxonomy_key, $args );
913 if ( is_wp_error( $usergroup ) )
914 return $usergroup;
915
916 return $this->get_usergroup_by( 'id', $usergroup['term_id'] );
917 }
918
919 /**
920 * Delete a usergroup based on its term ID
921 *
922 * @since 0.7
923 *
924 * @param int $id Unique ID for the Usergroup
925 * @param bool|WP_Error Returns true on success, WP_Error on failure
926 */
927 function delete_usergroup( $id ) {
928
929 $retval = wp_delete_term( $id, self::taxonomy_key );
930 return $retval;
931 }
932
933 /**
934 * Add an array of user logins or IDs to a given usergroup
935 *
936 * @since 0.7
937 *
938 * @param array $user_ids_or_logins User IDs or logins to be added to the usergroup
939 * @param int $id Usergroup to perform the action on
940 * @param bool $reset Delete all of the relationships before adding
941 * @return bool $success Whether or not we were successful
942 */
943 function add_users_to_usergroup( $user_ids_or_logins, $id, $reset = true ) {
944
945 if ( !is_array( $user_ids_or_logins ) )
946 return new WP_Error( 'invalid', __( "Invalid users variable. Should be array.", 'edit-flow' ) );
947
948 // To dump the existing users from a usergroup, we need to pass an empty array
949 $usergroup = $this->get_usergroup_by( 'id', $id );
950 if ( $reset ) {
951 $retval = $this->update_usergroup( $id, null, array() );
952 if ( is_wp_error( $retval ) )
953 return $retval;
954 }
955
956 // Add the new users one by one to an array we'll pass back to the usergroup
957 $new_users = array();
958 foreach ( (array)$user_ids_or_logins as $user_id_or_login ) {
959 if ( !is_numeric( $user_id_or_login ) )
960 $new_users[] = get_user_by( 'login', $user_id_or_login )->ID;
961 else
962 $new_users[] = (int)$user_id_or_login;
963 }
964 $retval = $this->update_usergroup( $id, null, $new_users );
965 if ( is_wp_error( $retval ) )
966 return $retval;
967 return true;
968 }
969
970 /**
971 * Add a given user to a Usergroup. Can use User ID or user login
972 *
973 * @since 0.7
974 *
975 * @param int|string $user_id_or_login User ID or login to be added to the Usergroups
976 * @param int|array $ids ID for the Usergroup(s)
977 * @return bool|WP_Error $retval Return true on success, WP_Error on error
978 */
979 function add_user_to_usergroup( $user_id_or_login, $ids ) {
980
981 if ( !is_numeric( $user_id_or_login ) )
982 $user_id = get_user_by( 'login', $user_id_or_login )->ID;
983 else
984 $user_id = (int)$user_id_or_login;
985
986 foreach( (array)$ids as $usergroup_id ) {
987 $usergroup = $this->get_usergroup_by( 'id', $usergroup_id );
988 $usergroup->user_ids[] = $user_id;
989 $retval = $this->update_usergroup( $usergroup_id, null, $usergroup->user_ids );
990 if ( is_wp_error( $retval ) )
991 return $retval;
992 }
993 return true;
994 }
995
996 /**
997 * Remove a given user from one or more usergroups
998 *
999 * @since 0.7
1000 *
1001 * @param int|string $user_id_or_login User ID or login to be removed from the Usergroups
1002 * @param int|array $ids ID for the Usergroup(s)
1003 * @return bool|WP_Error $retval Return true on success, WP_Error on error
1004 */
1005 function remove_user_from_usergroup( $user_id_or_login, $ids ) {
1006
1007 if ( !is_numeric( $user_id_or_login ) )
1008 $user_id = get_user_by( 'login', $user_id_or_login )->ID;
1009 else
1010 $user_id = (int)$user_id_or_login;
1011
1012 // Remove the user from each usergroup specified
1013 foreach( (array)$ids as $usergroup_id ) {
1014 $usergroup = $this->get_usergroup_by( 'id', $usergroup_id );
1015 // @todo I bet there's a PHP function for this I couldn't look up at 35,000 over the Atlantic
1016 foreach( $usergroup->user_ids as $key => $usergroup_user_id ) {
1017 if ( $usergroup_user_id == $user_id )
1018 unset( $usergroup->user_ids[$key] );
1019 }
1020 $retval = $this->update_usergroup( $usergroup_id, null, $usergroup->user_ids );
1021 if ( is_wp_error( $retval ) )
1022 return $retval;
1023 }
1024 return true;
1025
1026 }
1027
1028 /**
1029 * Get all of the Usergroup ids or objects for a given user
1030 *
1031 * @since 0.7
1032 *
1033 * @param int|string $user_id_or_login User ID or login to search against
1034 * @param array $ids_or_objects Whether to retrieve an array of IDs or usergroup objects
1035 * @param array|bool $usergroup_objects_or_ids Array of usergroup 'ids' or 'objects', false if none
1036 */
1037 function get_usergroups_for_user( $user_id_or_login, $ids_or_objects = 'ids' ) {
1038
1039 if ( !is_numeric( $user_id_or_login ) )
1040 $user_id = get_user_by( 'login', $user_id_or_login )->ID;
1041 else
1042 $user_id = (int)$user_id_or_login;
1043
1044 // Unfortunately, the easiest way to do this is get all usergroups
1045 // and then loop through each one to see if the user ID is stored
1046 $all_usergroups = $this->get_usergroups();
1047 if ( !empty( $all_usergroups) ) {
1048 $usergroup_objects_or_ids = array();
1049 foreach( $all_usergroups as $usergroup ) {
1050 // Not in this usergroup, so keep going
1051 if ( !in_array( $user_id, $usergroup->user_ids ) )
1052 continue;
1053 if ( $ids_or_objects == 'ids' )
1054 $usergroup_objects_or_ids[] = (int)$usergroup->term_id;
1055 else if ( $ids_or_objects == 'objects' )
1056 $usergroup_objects_or_ids[] = $usergroup;
1057 }
1058 return $usergroup_objects_or_ids;
1059 } else {
1060 return false;
1061 }
1062 }
1063
1064 }
1065
1066 }
1067
1068
1069 if ( !class_exists( 'EF_Usergroups_List_Table' ) ) {
1070 /**
1071 * Usergroups uses WordPress' List Table API for generating the Usergroup management table
1072 *
1073 * @since 0.7
1074 */
1075 class EF_Usergroups_List_Table extends WP_List_Table
1076 {
1077
1078 var $callback_args;
1079
1080 function __construct() {
1081
1082 parent::__construct( array(
1083 'plural' => 'user groups',
1084 'singular' => 'user group',
1085 'ajax' => true
1086 ) );
1087
1088 }
1089
1090 /**
1091 * @todo Paginate if we have a lot of usergroups
1092 *
1093 * @since 0.7
1094 */
1095 function prepare_items() {
1096 global $edit_flow;
1097
1098 $columns = $this->get_columns();
1099 $hidden = array();
1100 $sortable = array();
1101
1102 $this->_column_headers = array( $columns, $hidden, $sortable );
1103
1104 $this->items = $edit_flow->user_groups->get_usergroups();
1105
1106 $this->set_pagination_args( array(
1107 'total_items' => count( $this->items ),
1108 'per_page' => count( $this->items ),
1109 ) );
1110 }
1111
1112 /**
1113 * Message to be displayed when there are no usergroups
1114 *
1115 * @since 0.7
1116 */
1117 function no_items() {
1118 _e( 'No user groups found.', 'edit-flow' );
1119 }
1120
1121 /**
1122 * Columns in our Usergroups table
1123 *
1124 * @since 0.7
1125 */
1126 function get_columns() {
1127
1128 $columns = array(
1129 'name' => __( 'Name', 'edit-flow' ),
1130 'description' => __( 'Description', 'edit-flow' ),
1131 'users' => __( 'Users in Group', 'edit-flow' ),
1132 );
1133
1134 return $columns;
1135 }
1136
1137 /**
1138 * Process the Usergroup column value for all methods that aren't registered
1139 *
1140 * @since 0.7
1141 */
1142 function column_default( $usergroup, $column_name ) {
1143
1144
1145 }
1146
1147 /**
1148 * Process the Usergroup name column value.
1149 * Displays the name of the Usergroup, and action links
1150 *
1151 * @since 0.7
1152 */
1153 function column_name( $usergroup ) {
1154 global $edit_flow;
1155
1156 // @todo direct edit link
1157 $output = '<strong><a href="' . esc_url( $edit_flow->user_groups->get_link( array( 'action' => 'edit-usergroup', 'usergroup-id' => $usergroup->term_id ) ) ) . '">' . esc_html( $usergroup->name ) . '</a></strong>';
1158
1159 $actions = array();
1160 $actions['edit edit-usergroup'] = sprintf( '<a href="%1$s">' . __( 'Edit', 'edit-flow' ) . '</a>', $edit_flow->user_groups->get_link( array( 'action' => 'edit-usergroup', 'usergroup-id' => $usergroup->term_id ) ) );
1161 $actions['inline hide-if-no-js'] = '<a href="#" class="editinline">' . __( 'Quick&nbsp;Edit' ) . '</a>';
1162 $actions['delete delete-usergroup'] = sprintf( '<a href="%1$s">' . __( 'Delete', 'edit-flow' ) . '</a>', $edit_flow->user_groups->get_link( array( 'action' => 'delete-usergroup', 'usergroup-id' => $usergroup->term_id ) ) );
1163
1164 $output .= $this->row_actions( $actions, false );
1165 $output .= '<div class="hidden" id="inline_' . $usergroup->term_id . '">';
1166 $output .= '<div class="name">' . esc_html( $usergroup->name ) . '</div>';
1167 $output .= '<div class="description">' . esc_html( $usergroup->description ) . '</div>';
1168 $output .= '</div>';
1169
1170 return $output;
1171
1172 }
1173
1174 /**
1175 * Handle the 'description' column for the table of Usergroups
1176 * Don't need to unencode this because we already did when the usergroup was loaded
1177 *
1178 * @since 0.7
1179 */
1180 function column_description( $usergroup ) {
1181 return esc_html( $usergroup->description );
1182 }
1183
1184 /**
1185 * Show the "Total Users" in a given usergroup
1186 *
1187 * @since 0.7
1188 */
1189 function column_users( $usergroup ) {
1190 global $edit_flow;
1191 return '<a href="' . esc_url( $edit_flow->user_groups->get_link( array( 'action' => 'edit-usergroup', 'usergroup-id' => $usergroup->term_id ) ) ) . '">' . count( $usergroup->user_ids ) . '</a>';
1192 }
1193
1194 /**
1195 * Prepare a single row of information about a usergroup
1196 *
1197 * @since 0.7
1198 */
1199 function single_row( $usergroup ) {
1200 static $row_class = '';
1201 $row_class = ( $row_class == '' ? ' class="alternate"' : '' );
1202
1203 echo '<tr id="usergroup-' . $usergroup->term_id . '"' . $row_class . '>';
1204 echo $this->single_row_columns( $usergroup );
1205 echo '</tr>';
1206 }
1207
1208 /**
1209 * If we use this form, we can have inline editing!
1210 *
1211 * @since 0.7
1212 */
1213 function inline_edit() {
1214 global $edit_flow;
1215 ?>
1216 <form method="get" action=""><table style="display: none"><tbody id="inlineedit">
1217 <tr id="inline-edit" class="inline-edit-row" style="display: none"><td colspan="<?php echo $this->get_column_count(); ?>" class="colspanchange">
1218 <fieldset><div class="inline-edit-col">
1219 <h4><?php _e( 'Quick Edit' ); ?></h4>
1220 <label>
1221 <span class="title"><?php _e( 'Name', 'edit-flow' ); ?></span>
1222 <span class="input-text-wrap"><input type="text" name="name" class="ptitle" value="" maxlength="40" /></span>
1223 </label>
1224 <label>
1225 <span class="title"><?php _e( 'Description', 'edit-flow' ); ?></span>
1226 <span class="input-text-wrap"><input type="text" name="description" class="pdescription" value="" /></span>
1227 </label>
1228 </div></fieldset>
1229 <p class="inline-edit-save submit">
1230 <a accesskey="c" href="#inline-edit" title="<?php _e( 'Cancel' ); ?>" class="cancel button-secondary alignleft"><?php _e( 'Cancel' ); ?></a>
1231 <?php $update_text = __( 'Update User Group', 'edit-flow' ); ?>
1232 <a accesskey="s" href="#inline-edit" title="<?php echo esc_attr( $update_text ); ?>" class="save button-primary alignright"><?php echo $update_text; ?></a>
1233 <img class="waiting" style="display:none;" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
1234 <span class="error" style="display:none;"></span>
1235 <?php wp_nonce_field( 'usergroups-inline-edit-nonce', 'inline_edit', false ); ?>
1236 <br class="clear" />
1237 </p>
1238 </td></tr>
1239 </tbody></table></form>
1240 <?php
1241 }
1242
1243 }
1244 }
1245