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

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