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

1,252 lines 45.5 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 //Don't allow update of user groups from network
691 if ( ( !is_null( get_current_screen() ) ) && ( get_current_screen()->is_network ) )
692 return;
693
694 if ( current_user_can( $this->manage_usergroups_cap ) && wp_verify_nonce( $_POST['ef_edit_profile_usergroups_nonce'], 'ef_edit_profile_usergroups_nonce' ) ) {
695 // Sanitize the data and save
696 // Gracefully handle the case where the user was unsubscribed from all usergroups
697 $usergroups = isset( $_POST['ef_usergroups'] ) ? array_map( 'intval', (array)$_POST['ef_usergroups'] ) : array();
698 $all_usergroups = $this->get_usergroups();
699 foreach( $all_usergroups as $usergroup ) {
700 if ( in_array( $usergroup->term_id, $usergroups ) )
701 $this->add_user_to_usergroup( $user->ID, $usergroup->term_id );
702 else
703 $this->remove_user_from_usergroup( $user->ID, $usergroup->term_id );
704 }
705 }
706
707 return array( &$errors, $update, &$user );
708 }
709
710 /**
711 * Generate a link to one of the usergroups actions
712 *
713 * @since 0.7
714 *
715 * @param string $action Action we want the user to take
716 * @param array $args Any query args to add to the URL
717 * @return string $link Direct link to delete a usergroup
718 */
719 function get_link( $args = array() ) {
720 if ( !isset( $args['action'] ) )
721 $args['action'] = '';
722 if ( !isset( $args['page'] ) )
723 $args['page'] = $this->module->settings_slug;
724 // Add other things we may need depending on the action
725 switch( $args['action'] ) {
726 case 'delete-usergroup':
727 $args['nonce'] = wp_create_nonce( $args['action'] );
728 break;
729 default:
730 break;
731 }
732 return add_query_arg( $args, get_admin_url( null, 'admin.php' ) );
733 }
734
735 /**
736 * Displays a list of usergroups with checkboxes
737 *
738 * @since 0.7
739 *
740 * @param array $selected List of usergroup keys that should be checked
741 * @param array $args ???
742 */
743 function usergroups_select_form( $selected = array(), $args = null ) {
744
745 // TODO add $args for additional options
746 // e.g. showing members assigned to group (John Smith, Jane Doe, and 9 others)
747 // before <tag>, after <tag>, class, id names?
748 $defaults = array(
749 'list_class' => 'ef-post_following_list',
750 'list_id' => 'ef-following_usergroups',
751 'input_id' => 'following_usergroups'
752 );
753
754 $parsed_args = wp_parse_args( $args, $defaults );
755 extract( $parsed_args, EXTR_SKIP );
756 $usergroups = $this->get_usergroups();
757 if ( empty($usergroups) ) {
758 ?>
759 <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>
760 <?php
761 } else {
762
763 ?>
764 <ul id="<?php echo $list_id ?>" class="<?php echo $list_class ?>">
765 <?php
766 foreach( $usergroups as $usergroup ) {
767 $checked = ( in_array( $usergroup->term_id, $selected ) ) ? ' checked="checked"' : '';
768 ?>
769 <li>
770 <label for="<?php echo $input_id . esc_attr( $usergroup->term_id ); ?>" title="<?php echo esc_attr($usergroup->description) ?>">
771 <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 ?> />
772 <span class="ef-usergroup_name"><?php echo esc_html( $usergroup->name ); ?></span>
773 <span class="ef-usergroup_description" title="<?php echo esc_attr($usergroup->description) ?>">
774 <?php echo (strlen($usergroup->description) >= 50) ? substr_replace(esc_html($usergroup->description), '...', 50) : esc_html($usergroup->description); ?>
775 </span>
776 </label>
777 </li>
778 <?php
779 }
780 ?>
781 </ul>
782 <?php
783 }
784 }
785
786 /**
787 * Core Usergroups Module Functionality
788 */
789
790 /**
791 * Get all of the registered usergroups. Returns an array of objects
792 *
793 * @since 0.7
794 *
795 * @param array $args Arguments to filter/sort by
796 * @return array|bool $usergroups Array of Usergroups with relevant data, false if none
797 */
798 function get_usergroups( $args = array() ) {
799
800 // We want empty terms by default
801 if ( !isset( $args['hide_empty'] ) )
802 $args['hide_empty'] = 0;
803
804 $usergroup_terms = get_terms( self::taxonomy_key, $args );
805 if ( !$usergroup_terms )
806 return false;
807
808 // Run the usergroups through get_usergroup_by() so we load users too
809 $usergroups = array();
810 foreach( $usergroup_terms as $usergroup_term ) {
811 $usergroups[] = $this->get_usergroup_by( 'id', $usergroup_term->term_id );
812 }
813 return $usergroups;
814 }
815
816 /**
817 * Get all of the data associated with a single usergroup
818 * Usergroup contains:
819 * - ID (key = term_id)
820 * - Slug (prefixed with our special key to avoid conflicts)
821 * - Name
822 * - Description
823 * - User IDs (array of IDs)
824 *
825 * @since 0.7
826 *
827 * @param string $field 'id', 'name', or 'slug'
828 * @param int|string $value Value for the search field
829 * @return object|array|WP_Error $usergroup Usergroup information as specified by $output
830 */
831 function get_usergroup_by( $field, $value ) {
832
833 $usergroup = get_term_by( $field, $value, self::taxonomy_key );
834
835 if ( !$usergroup || is_wp_error( $usergroup ) )
836 return $usergroup;
837
838 // We're using an encoded description field to store extra values
839 // Declare $user_ids ahead of time just in case it's empty
840 $usergroup->user_ids = array();
841 $unencoded_description = $this->get_unencoded_description( $usergroup->description );
842 if ( is_array( $unencoded_description ) ) {
843 foreach( $unencoded_description as $key => $value ) {
844 $usergroup->$key = $value;
845 }
846 }
847 return $usergroup;
848 }
849
850 /**
851 * Create a new usergroup containing:
852 * - Name
853 * - Slug (prefixed with our special key to avoid conflicts)
854 * - Description
855 * - Users
856 *
857 * @since 0.7
858 *
859 * @param array $args Name (optional), slug and description for the usergroup
860 * @param array $user_ids IDs for the users to be added to the Usergroup
861 * @return object|WP_Error $usergroup Object for the new Usergroup on success, WP_Error otherwise
862 */
863 function add_usergroup( $args = array(), $user_ids = array() ) {
864
865 if ( !isset( $args['name'] ) )
866 return new WP_Error( 'invalid', __( 'New user groups must have a name', 'edit-flow' ) );
867
868 $name = $args['name'];
869 $default = array(
870 'name' => '',
871 'slug' => self::term_prefix . sanitize_title( $name ),
872 'description' => '',
873 );
874 $args = array_merge( $default, $args );
875
876 // Encode our extra fields and then store them in the description field
877 $args_to_encode = array(
878 'description' => $args['description'],
879 'user_ids' => array_unique( $user_ids ),
880 );
881 $encoded_description = $this->get_encoded_description( $args_to_encode );
882 $args['description'] = $encoded_description;
883 $usergroup = wp_insert_term( $name, self::taxonomy_key, $args );
884 if ( is_wp_error( $usergroup ) )
885 return $usergroup;
886
887 return $this->get_usergroup_by( 'id', $usergroup['term_id'] );
888 }
889
890 /**
891 * Update a usergroup with new data.
892 * Fields can include:
893 * - Name
894 * - Slug (prefixed with our special key, of course)
895 * - Description
896 * - Users
897 *
898 * @since 0.7
899 *
900 * @param int $id Unique ID for the usergroup
901 * @param array $args Usergroup meta to update (name, slug, description)
902 * @param array $users Users to be added to the Usergroup. If set, removes existing users first.
903 * @return object|WP_Error $usergroup Object for the updated Usergroup on success, WP_Error otherwise
904 */
905 function update_usergroup( $id, $args = array(), $users = null ) {
906
907 $existing_usergroup = $this->get_usergroup_by( 'id', $id );
908 if ( is_wp_error( $existing_usergroup ) )
909 return new WP_Error( 'invalid', __( "User group doesn't exist.", 'edit-flow' ) );
910
911 // Encode our extra fields and then store them in the description field
912 $args_to_encode = array();
913 $args_to_encode['description'] = ( isset( $args['description'] ) ) ? $args['description'] : $existing_usergroup->description;
914 $args_to_encode['user_ids'] = ( is_array( $users ) ) ? $users : $existing_usergroup->user_ids;
915 $args_to_encode['user_ids'] = array_unique( $args_to_encode['user_ids'] );
916 $encoded_description = $this->get_encoded_description( $args_to_encode );
917 $args['description'] = $encoded_description;
918
919 $usergroup = wp_update_term( $id, self::taxonomy_key, $args );
920 if ( is_wp_error( $usergroup ) )
921 return $usergroup;
922
923 return $this->get_usergroup_by( 'id', $usergroup['term_id'] );
924 }
925
926 /**
927 * Delete a usergroup based on its term ID
928 *
929 * @since 0.7
930 *
931 * @param int $id Unique ID for the Usergroup
932 * @param bool|WP_Error Returns true on success, WP_Error on failure
933 */
934 function delete_usergroup( $id ) {
935
936 $retval = wp_delete_term( $id, self::taxonomy_key );
937 return $retval;
938 }
939
940 /**
941 * Add an array of user logins or IDs to a given usergroup
942 *
943 * @since 0.7
944 *
945 * @param array $user_ids_or_logins User IDs or logins to be added to the usergroup
946 * @param int $id Usergroup to perform the action on
947 * @param bool $reset Delete all of the relationships before adding
948 * @return bool $success Whether or not we were successful
949 */
950 function add_users_to_usergroup( $user_ids_or_logins, $id, $reset = true ) {
951
952 if ( !is_array( $user_ids_or_logins ) )
953 return new WP_Error( 'invalid', __( "Invalid users variable. Should be array.", 'edit-flow' ) );
954
955 // To dump the existing users from a usergroup, we need to pass an empty array
956 $usergroup = $this->get_usergroup_by( 'id', $id );
957 if ( $reset ) {
958 $retval = $this->update_usergroup( $id, null, array() );
959 if ( is_wp_error( $retval ) )
960 return $retval;
961 }
962
963 // Add the new users one by one to an array we'll pass back to the usergroup
964 $new_users = array();
965 foreach ( (array)$user_ids_or_logins as $user_id_or_login ) {
966 if ( !is_numeric( $user_id_or_login ) )
967 $new_users[] = get_user_by( 'login', $user_id_or_login )->ID;
968 else
969 $new_users[] = (int)$user_id_or_login;
970 }
971 $retval = $this->update_usergroup( $id, null, $new_users );
972 if ( is_wp_error( $retval ) )
973 return $retval;
974 return true;
975 }
976
977 /**
978 * Add a given user to a Usergroup. Can use User ID or user login
979 *
980 * @since 0.7
981 *
982 * @param int|string $user_id_or_login User ID or login to be added to the Usergroups
983 * @param int|array $ids ID for the Usergroup(s)
984 * @return bool|WP_Error $retval Return true on success, WP_Error on error
985 */
986 function add_user_to_usergroup( $user_id_or_login, $ids ) {
987
988 if ( !is_numeric( $user_id_or_login ) )
989 $user_id = get_user_by( 'login', $user_id_or_login )->ID;
990 else
991 $user_id = (int)$user_id_or_login;
992
993 foreach( (array)$ids as $usergroup_id ) {
994 $usergroup = $this->get_usergroup_by( 'id', $usergroup_id );
995 $usergroup->user_ids[] = $user_id;
996 $retval = $this->update_usergroup( $usergroup_id, null, $usergroup->user_ids );
997 if ( is_wp_error( $retval ) )
998 return $retval;
999 }
1000 return true;
1001 }
1002
1003 /**
1004 * Remove a given user from one or more usergroups
1005 *
1006 * @since 0.7
1007 *
1008 * @param int|string $user_id_or_login User ID or login to be removed from the Usergroups
1009 * @param int|array $ids ID for the Usergroup(s)
1010 * @return bool|WP_Error $retval Return true on success, WP_Error on error
1011 */
1012 function remove_user_from_usergroup( $user_id_or_login, $ids ) {
1013
1014 if ( !is_numeric( $user_id_or_login ) )
1015 $user_id = get_user_by( 'login', $user_id_or_login )->ID;
1016 else
1017 $user_id = (int)$user_id_or_login;
1018
1019 // Remove the user from each usergroup specified
1020 foreach( (array)$ids as $usergroup_id ) {
1021 $usergroup = $this->get_usergroup_by( 'id', $usergroup_id );
1022 // @todo I bet there's a PHP function for this I couldn't look up at 35,000 over the Atlantic
1023 foreach( $usergroup->user_ids as $key => $usergroup_user_id ) {
1024 if ( $usergroup_user_id == $user_id )
1025 unset( $usergroup->user_ids[$key] );
1026 }
1027 $retval = $this->update_usergroup( $usergroup_id, null, $usergroup->user_ids );
1028 if ( is_wp_error( $retval ) )
1029 return $retval;
1030 }
1031 return true;
1032
1033 }
1034
1035 /**
1036 * Get all of the Usergroup ids or objects for a given user
1037 *
1038 * @since 0.7
1039 *
1040 * @param int|string $user_id_or_login User ID or login to search against
1041 * @param array $ids_or_objects Whether to retrieve an array of IDs or usergroup objects
1042 * @param array|bool $usergroup_objects_or_ids Array of usergroup 'ids' or 'objects', false if none
1043 */
1044 function get_usergroups_for_user( $user_id_or_login, $ids_or_objects = 'ids' ) {
1045
1046 if ( !is_numeric( $user_id_or_login ) )
1047 $user_id = get_user_by( 'login', $user_id_or_login )->ID;
1048 else
1049 $user_id = (int)$user_id_or_login;
1050
1051 // Unfortunately, the easiest way to do this is get all usergroups
1052 // and then loop through each one to see if the user ID is stored
1053 $all_usergroups = $this->get_usergroups();
1054 if ( !empty( $all_usergroups) ) {
1055 $usergroup_objects_or_ids = array();
1056 foreach( $all_usergroups as $usergroup ) {
1057 // Not in this usergroup, so keep going
1058 if ( !in_array( $user_id, $usergroup->user_ids ) )
1059 continue;
1060 if ( $ids_or_objects == 'ids' )
1061 $usergroup_objects_or_ids[] = (int)$usergroup->term_id;
1062 else if ( $ids_or_objects == 'objects' )
1063 $usergroup_objects_or_ids[] = $usergroup;
1064 }
1065 return $usergroup_objects_or_ids;
1066 } else {
1067 return false;
1068 }
1069 }
1070
1071 }
1072
1073 }
1074
1075
1076 if ( !class_exists( 'EF_Usergroups_List_Table' ) ) {
1077 /**
1078 * Usergroups uses WordPress' List Table API for generating the Usergroup management table
1079 *
1080 * @since 0.7
1081 */
1082 class EF_Usergroups_List_Table extends WP_List_Table
1083 {
1084
1085 var $callback_args;
1086
1087 function __construct() {
1088
1089 parent::__construct( array(
1090 'plural' => 'user groups',
1091 'singular' => 'user group',
1092 'ajax' => true
1093 ) );
1094
1095 }
1096
1097 /**
1098 * @todo Paginate if we have a lot of usergroups
1099 *
1100 * @since 0.7
1101 */
1102 function prepare_items() {
1103 global $edit_flow;
1104
1105 $columns = $this->get_columns();
1106 $hidden = array();
1107 $sortable = array();
1108
1109 $this->_column_headers = array( $columns, $hidden, $sortable );
1110
1111 $this->items = $edit_flow->user_groups->get_usergroups();
1112
1113 $this->set_pagination_args( array(
1114 'total_items' => count( $this->items ),
1115 'per_page' => count( $this->items ),
1116 ) );
1117 }
1118
1119 /**
1120 * Message to be displayed when there are no usergroups
1121 *
1122 * @since 0.7
1123 */
1124 function no_items() {
1125 _e( 'No user groups found.', 'edit-flow' );
1126 }
1127
1128 /**
1129 * Columns in our Usergroups table
1130 *
1131 * @since 0.7
1132 */
1133 function get_columns() {
1134
1135 $columns = array(
1136 'name' => __( 'Name', 'edit-flow' ),
1137 'description' => __( 'Description', 'edit-flow' ),
1138 'users' => __( 'Users in Group', 'edit-flow' ),
1139 );
1140
1141 return $columns;
1142 }
1143
1144 /**
1145 * Process the Usergroup column value for all methods that aren't registered
1146 *
1147 * @since 0.7
1148 */
1149 function column_default( $usergroup, $column_name ) {
1150
1151
1152 }
1153
1154 /**
1155 * Process the Usergroup name column value.
1156 * Displays the name of the Usergroup, and action links
1157 *
1158 * @since 0.7
1159 */
1160 function column_name( $usergroup ) {
1161 global $edit_flow;
1162
1163 // @todo direct edit link
1164 $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>';
1165
1166 $actions = array();
1167 $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 ) ) );
1168 $actions['inline hide-if-no-js'] = '<a href="#" class="editinline">' . __( 'Quick&nbsp;Edit' ) . '</a>';
1169 $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 ) ) );
1170
1171 $output .= $this->row_actions( $actions, false );
1172 $output .= '<div class="hidden" id="inline_' . $usergroup->term_id . '">';
1173 $output .= '<div class="name">' . esc_html( $usergroup->name ) . '</div>';
1174 $output .= '<div class="description">' . esc_html( $usergroup->description ) . '</div>';
1175 $output .= '</div>';
1176
1177 return $output;
1178
1179 }
1180
1181 /**
1182 * Handle the 'description' column for the table of Usergroups
1183 * Don't need to unencode this because we already did when the usergroup was loaded
1184 *
1185 * @since 0.7
1186 */
1187 function column_description( $usergroup ) {
1188 return esc_html( $usergroup->description );
1189 }
1190
1191 /**
1192 * Show the "Total Users" in a given usergroup
1193 *
1194 * @since 0.7
1195 */
1196 function column_users( $usergroup ) {
1197 global $edit_flow;
1198 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>';
1199 }
1200
1201 /**
1202 * Prepare a single row of information about a usergroup
1203 *
1204 * @since 0.7
1205 */
1206 function single_row( $usergroup ) {
1207 static $row_class = '';
1208 $row_class = ( $row_class == '' ? ' class="alternate"' : '' );
1209
1210 echo '<tr id="usergroup-' . $usergroup->term_id . '"' . $row_class . '>';
1211 echo $this->single_row_columns( $usergroup );
1212 echo '</tr>';
1213 }
1214
1215 /**
1216 * If we use this form, we can have inline editing!
1217 *
1218 * @since 0.7
1219 */
1220 function inline_edit() {
1221 global $edit_flow;
1222 ?>
1223 <form method="get" action=""><table style="display: none"><tbody id="inlineedit">
1224 <tr id="inline-edit" class="inline-edit-row" style="display: none"><td colspan="<?php echo $this->get_column_count(); ?>" class="colspanchange">
1225 <fieldset><div class="inline-edit-col">
1226 <h4><?php _e( 'Quick Edit' ); ?></h4>
1227 <label>
1228 <span class="title"><?php _e( 'Name', 'edit-flow' ); ?></span>
1229 <span class="input-text-wrap"><input type="text" name="name" class="ptitle" value="" maxlength="40" /></span>
1230 </label>
1231 <label>
1232 <span class="title"><?php _e( 'Description', 'edit-flow' ); ?></span>
1233 <span class="input-text-wrap"><input type="text" name="description" class="pdescription" value="" /></span>
1234 </label>
1235 </div></fieldset>
1236 <p class="inline-edit-save submit">
1237 <a accesskey="c" href="#inline-edit" title="<?php _e( 'Cancel' ); ?>" class="cancel button-secondary alignleft"><?php _e( 'Cancel' ); ?></a>
1238 <?php $update_text = __( 'Update User Group', 'edit-flow' ); ?>
1239 <a accesskey="s" href="#inline-edit" title="<?php echo esc_attr( $update_text ); ?>" class="save button-primary alignright"><?php echo $update_text; ?></a>
1240 <img class="waiting" style="display:none;" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
1241 <span class="error" style="display:none;"></span>
1242 <?php wp_nonce_field( 'usergroups-inline-edit-nonce', 'inline_edit', false ); ?>
1243 <br class="clear" />
1244 </p>
1245 </td></tr>
1246 </tbody></table></form>
1247 <?php
1248 }
1249
1250 }
1251 }
1252