PluginProbe
Edit Flow / 0.9.1
Edit Flow v0.9.1
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.9.1, at modules/user-groups/user-groups.php

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