PluginProbe
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor / 4.0.3
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor v4.0.3
4.0.3 4.0.2 4.0.1 4.0.0 3.16.6 3.16.5 3.16.4 3.16.3 3.16.2 3.16.1 3.16.0 3.15.9 3.9.9 3.9.5 3.9.6 3.9.7 3.9.8 1.1.7 1.1.8 1.1.9 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 341 releases
← All changes | features/email-confirmation/class-email-confirmation.php +189 -109 2.0.3 → 4.0.3 View file →
@@ -1,5 +1,8 @@
1 1 <?php
2 +// Exit if accessed directly
3 +if ( ! defined( 'ABSPATH' ) ) exit;
4 +
2 5 /*
3 6 Code taken from: Custom List Table Example (plugin)
4 7 Author: Matt Van Andel
5 8 Author URI: http://www.mattvanandel.com
@@ -10,9 +13,9 @@
10 13 * The PB_WP_List_Table class isn't automatically available to plugins, so we need
11 14 * to check if it's available and load it if necessary.
12 15 */
13 16 if( !class_exists( 'PB_WP_List_Table' ) ){
14 - require_once( WPPB_PLUGIN_DIR.'/features/class-list-table.php' );
17 + require_once( WPPB_PLUGIN_DIR.'/assets/lib/class-list-table.php' );
15 18 }
16 19
17 20
18 21
@@ -72,10 +75,30 @@
72 75 **************************************************************************/
73 76 function column_default($item, $column_name){
74 77 switch($column_name){
75 78 case 'email':
79 + return esc_html( $item[$column_name] );
76 80 case 'registered':
77 - return $item[$column_name];
81 + return date_i18n( "Y-m-d G:i:s", wppb_add_gmt_offset( strtotime( $item[$column_name] ) ) );
82 + case 'user-meta':
83 + global $wpdb;
84 + $sql_result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE user_email = %s", $item['email'] ), ARRAY_A );
85 + $user_meta = $sql_result['meta'];
86 + $user_meta_lines = array();
87 + if ( ! empty( $user_meta ) ) {
88 + foreach ( maybe_unserialize( $user_meta ) as $key => $value ) {
89 + if ( 'user_pass' === $key ) {
90 + continue;
91 + }
92 + if ( is_array( $value ) ) {
93 + $value = implode( ',', $value );
94 + }
95 + $user_meta_lines[] = esc_html( (string) $key ) . ':' . esc_html( (string) $value );
96 + }
97 + }
98 + $user_meta_html = '<div><pre>' . implode( "\n", $user_meta_lines ) . '</pre></div>';
99 + $dialog_js = 'jQuery(\'' . esc_js( $user_meta_html ) . '\').dialog({title:\'' . esc_js( __( 'User Meta', 'profile-builder' ) ) . '\', width: 500 }); return false;';
100 + return '<a href="#" data-email="' . esc_attr( $item['email'] ) . '" onclick="' . esc_attr( $dialog_js ) . '">' . esc_html__( 'show', 'profile-builder' ) . '</a>';
78 101 default:
79 102 return print_r($item,true); //Show the whole array for troubleshooting purposes
80 103 }
81 104 }
@@ -80,8 +103,22 @@
80 103 }
81 104 }
82 105
83 106
107 + /**
108 + * Unconfirmed-user row action. Args live on data attributes so the email is never interpolated into JavaScript.
109 + */
110 + function wppb_ec_action_link( $url, $todo, $email, $confirm_message, $label ) {
111 + return sprintf(
112 + '<a href="#" class="wppb-ec-action" data-url="%1$s" data-todo="%2$s" data-email="%3$s" data-message="%4$s">%5$s</a>',
113 + esc_url( $url ),
114 + esc_attr( $todo ),
115 + esc_attr( $email ),
116 + esc_attr( $confirm_message ),
117 + esc_html( $label )
118 + );
119 + }
120 +
84 121 /** ************************************************************************
85 122 * Recommended. This is a custom column method and is responsible for what
86 123 * is rendered in any column with a name/slug of 'username'. Every time the class
87 124 * needs to render a column, it first looks for a method named
@@ -96,23 +133,24 @@
96 133 * @see PB_WP_List_Table::::single_row_columns()
97 134 * @param array $item A singular item (one full row's worth of data)
98 135 * @return string Text to be placed inside the column <td>
99 136 **************************************************************************/
100 - function column_username($item){
137 + function column_username( $item ) {
101 138
102 139 $GRavatar = get_avatar( $item['email'], 32, '' );
103 -
104 - //Build row actions
140 + $current_url = wppb_curpageurl();
141 + $email = $item['ID'];
142 +
105 143 $actions = array(
106 - 'delete' => sprintf( '<a href="javascript:confirmECAction( \'%s\', \'%s\', \'%s\', \'' . __( 'delete this user from the _signups table?', 'profilebuilder' ) . '\' )">' . __( 'Delete', 'profilebuilder' ) . '</a>', wppb_curpageurl(), 'delete', $item['ID'] ),
107 - 'confirm' => sprintf( '<a href="javascript:confirmECAction( \'%s\', \'%s\', \'%s\', \'' . __( 'confirm this email yourself?', 'profilebuilder' ) . '\' )">' . __( 'Confirm Email', 'profilebuilder' ) . '</a>', wppb_curpageurl(), 'confirm', $item['ID'] ),
108 - 'resend' => sprintf( '<a href="javascript:confirmECAction( \'%s\', \'%s\', \'%s\', \'' . __( 'resend the activation link?', 'profilebuilder' ) . '\' )">' . __( 'Resend Activation Email', 'profilebuilder' ) . '</a>', wppb_curpageurl(), 'resend', $item['ID'] )
144 + 'delete' => $this->wppb_ec_action_link( $current_url, 'delete', $email, __( 'delete this user from the _signups table?', 'profile-builder' ), __( 'Delete', 'profile-builder' ) ),
145 + 'confirm' => $this->wppb_ec_action_link( $current_url, 'confirm', $email, __( 'confirm this email yourself?', 'profile-builder' ), __( 'Confirm Email', 'profile-builder' ) ),
146 + 'resend' => $this->wppb_ec_action_link( $current_url, 'resend', $email, __( 'resend the activation link?', 'profile-builder' ), __( 'Resend Activation Email', 'profile-builder' ) ),
109 147 );
110 148
111 149 //Return the user row
112 150 return sprintf('%1$s <strong>%2$s</strong> %3$s',
113 151 /*$1%s*/ $GRavatar,
114 - /*$2%s*/ $item['username'],
152 + /*$2%s*/ esc_html( $item['username'] ),
115 153 /*$3%s*/ $this->row_actions($actions)
116 154 );
117 155 }
118 156
@@ -127,10 +165,10 @@
127 165 **************************************************************************/
128 166 function column_cb($item){
129 167 return sprintf(
130 168 '<input type="checkbox" name="%1$s[]" value="%2$s" />',
131 - /*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label
132 - /*$2%s*/ $item['ID'] //The value of the checkbox should be the record's id
169 + /*$1%s*/ esc_attr( $this->_args['singular'] ),
170 + /*$2%s*/ esc_attr( $item['ID'] )
133 171 );
134 172 }
135 173
136 174
@@ -149,11 +187,12 @@
149 187 **************************************************************************/
150 188 function get_columns(){
151 189 $columns = array(
152 190 'cb' => '<input type="checkbox" />', //Render a checkbox instead of text
153 - 'username' => __( 'Username', 'profilebuilder' ),
154 - 'email' => __( 'E-mail', 'profilebuilder' ),
155 - 'registered' => __( 'Registered', 'profilebuilder' )
191 + 'username' => __( 'Username', 'profile-builder' ),
192 + 'email' => __( 'Email', 'profile-builder' ),
193 + 'registered' => __( 'Registered', 'profile-builder' ),
194 + 'user-meta' => __( 'User Meta', 'profile-builder' )
156 195 );
157 196
158 197 return $columns;
159 198 }
@@ -198,11 +237,11 @@
198 237 * @return array An associative array containing all the bulk actions: 'slugs'=>'Visible Titles'
199 238 **************************************************************************/
200 239 function get_bulk_actions() {
201 240 $actions = array(
202 - 'delete' => __( 'Delete', 'profilebuilder' ),
203 - 'confirm' => __( 'Confirm Email', 'profilebuilder' ),
204 - 'resend' => __( 'Resend Activation Email', 'profilebuilder' )
241 + 'delete' => __( 'Delete', 'profile-builder' ),
242 + 'confirm' => __( 'Confirm Email', 'profile-builder' ),
243 + 'resend' => __( 'Resend Activation Email', 'profile-builder' )
205 244 );
206 245
207 246 return $actions;
208 247 }
@@ -217,51 +256,64 @@
217 256 **************************************************************************/
218 257
219 258 function wppb_process_bulk_action_message( $message, $url ){
220 259
221 - echo "<script type=\"text/javascript\">confirmECActionBulk( '".$url."', '".$message."' )</script>";
260 + echo '<script type=\'text/javascript\'>confirmECActionBulk( "'.esc_js( $url ).'", "'.esc_js( $message ).'" )</script>';
222 261 }
223 262
224 263 function wppb_process_bulk_action() {
225 264 global $current_user;
226 265 global $wpdb;
227 -
228 - if ( current_user_can( 'delete_users' ) ){
266 +
267 + // Only verify and process when a bulk action is actually being submitted through the list-table form.
268 + if ( false === $this->current_action() )
269 + return;
270 +
271 + // CSRF protection: the bulk-action form rendered by display() already outputs a 'bulk-{plural}' nonce, verify it here.
272 + check_admin_referer( 'bulk-' . $this->_args['plural'] );
273 +
274 + if ( current_user_can( apply_filters( 'wppb_email_confirmation_user_capability', 'manage_options' ) ) ){
229 275 if( 'delete' === $this->current_action() ) {
230 - foreach ( $_GET['user'] as $user ){
231 - $sql_result = $wpdb->query( $wpdb->prepare( "DELETE FROM ".$wpdb->prefix."signups WHERE user_email = %s", $user ) );
232 -
233 - if ( !$sql_result )
234 - $this->wppb_process_bulk_action_message( sprintf( __( "%s couldn't be deleted", "profilebuilder" ), $result->user_login ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' );
276 + if( !empty( $_GET['user'] ) && is_array( $_GET['user'] ) ) {
277 + foreach ( array_map( 'sanitize_email', $_GET['user'] ) as $user) {
278 + $sql_result = $wpdb->query($wpdb->prepare("DELETE FROM " . $wpdb->base_prefix . "signups WHERE user_email = %s", $user));
235 279
236 - }
280 + if (!$sql_result)
281 + $this->wppb_process_bulk_action_message(sprintf(__("%s couldn't be deleted", "profile-builder"), $user), get_bloginfo('url') . '/wp-admin/users.php?page=unconfirmed_emails');
282 +
283 + }
284 + }
237 285
238 - $this->wppb_process_bulk_action_message( __( 'All users have been successfully deleted', 'profilebuilder' ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' );
286 + $this->wppb_process_bulk_action_message( __( 'All users have been successfully deleted', 'profile-builder' ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' );
239 287
240 288 }elseif( 'confirm' === $this->current_action() ) {
241 - foreach ( $_GET['user'] as $user ){
242 - $sql_result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->prefix . "signups WHERE user_email = %s", $user ), ARRAY_A );
243 -
244 - if ( $sql_result )
245 - wppb_manual_activate_signup( $sql_result->activation_key );
246 - }
289 + if( !empty( $_GET['user'] ) && is_array( $_GET['user'] ) ) {
290 + foreach ( array_map( 'sanitize_email', $_GET['user'] ) as $user) {
291 + $sql_result = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $wpdb->base_prefix . "signups WHERE user_email = %s", $user), ARRAY_A);
247 292
248 - $this->wppb_process_bulk_action_message( __( 'The selected users have been activated', 'profilebuilder' ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' );
293 + if ($sql_result)
294 + wppb_manual_activate_signup($sql_result['activation_key']);
295 + }
296 + }
297 +
298 + $this->wppb_process_bulk_action_message( __( 'The selected users have been activated', 'profile-builder' ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' );
249 299
250 300 }elseif( 'resend' === $this->current_action() ) {
251 - foreach ( $_GET['user'] as $user ){
252 - $sql_result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->prefix . "signups WHERE user_email = %s", $user ), ARRAY_A );
253 -
254 - if ( $sql_result )
255 - wppb_signup_user_notification( esc_sql( $sql_result['user_login'] ), esc_sql( $sql_result['user_email'] ), $sql_result['activation_key'], $sql_result['meta'] );
301 + if( !empty( $_GET['user'] ) && is_array( $_GET['user'] ) ) {
302 + foreach ( array_map( 'sanitize_email', $_GET['user'] ) as $user ) {
303 + $sql_result = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $wpdb->base_prefix . "signups WHERE user_email = %s", $user), ARRAY_A);
256 304
257 - }
305 + if ($sql_result)
306 + wppb_signup_user_notification(esc_sql($sql_result['user_login']), esc_sql($sql_result['user_email']), $sql_result['activation_key'], $sql_result['meta']);
258 307
259 - $this->wppb_process_bulk_action_message( __( 'The selected users have had their activation emails resent', 'profilebuilder' ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' );
308 + }
309 + }
310 +
311 + $this->wppb_process_bulk_action_message( __( 'The selected users have had their activation emails resent', 'profile-builder' ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' );
260 312 }
261 313
262 314 }else
263 - $this->wppb_process_bulk_action_message( __( "Sorry, but you don't have permission to do that!", "profilebuilder" ), get_bloginfo('url').'/wp-admin/' );
315 + $this->wppb_process_bulk_action_message( __( "Sorry, but you don't have permission to do that!", "profile-builder" ), get_bloginfo('url').'/wp-admin/' );
264 316 }
265 317
266 318
267 319 /** ************************************************************************
@@ -282,24 +334,69 @@
282 334 function prepare_items() {
283 335 global $wpdb;
284 336
285 337 $this->dataArray = array();
286 - $iterator = 0;
338 +
339 + /**
340 + * First, lets decide how many records per page to show
341 + */
342 + $per_page = get_user_meta( get_current_user_id(), 'users_per_page', true );
343 + if( !empty($per_page) )
344 + $per_page = apply_filters('wppb_email_confirmation_user_per_page_number', $per_page);
345 + else
346 + $per_page = apply_filters('wppb_email_confirmation_user_per_page_number', 20);
347 +
348 + /* determine offset */
349 + if( !empty( $_REQUEST['paged'] ) ){
350 + $offset = ( sanitize_text_field( $_REQUEST['paged'] ) -1 ) * $per_page;
351 + }
352 + else
353 + $offset = 0;
354 +
355 + /* handle order and orderby attr */
356 + if( !empty( $_REQUEST['orderby'] ) ){
357 +
358 + $orderby = sanitize_sql_orderby( $_REQUEST['orderby'] );
359 +
360 + if( $orderby == 'username' )
361 + $orderby = 'user_login';
362 + elseif ( $orderby == 'email' )
363 + $orderby = 'user_email';
364 +
365 + } else
366 + $orderby = 'user_login';
367 +
368 + if( !empty( $_REQUEST['order'] ) && sanitize_text_field( $_REQUEST['order'] ) === 'desc' )
369 + $order = "DESC";
370 + else
371 + $order = 'ASC';
372 +
373 + /* handle the WHERE clause */
374 + $where = "active = 0";
375 + if( isset( $_REQUEST['s'] ) && !empty( $_REQUEST['s'] ) ){
376 + $where .= $wpdb->prepare( " AND ( user_login LIKE %s OR user_email LIKE %s OR registered LIKE %s )", '%' . sanitize_text_field( $_REQUEST['s'] ) . '%', '%' . sanitize_text_field( $_REQUEST['s'] ) . '%' , '%' . sanitize_text_field( $_REQUEST['s'] ) . '%' );
377 + }
378 + /* since version 2.0.7 for multisite we add a 'registered_for_blog_id' meta in the registration process
379 + so we can display only the users registered on that blog. Also for backwards compatibility we display the users that don't have that meta at all */
380 + if( is_multisite() ){
381 + $where .= $wpdb->prepare( " AND ( meta NOT LIKE '%\"registered_for_blog_id\"%' OR meta LIKE '%s' )", '%\"registered_for_blog_id\";i:'.get_current_blog_id().'%' );
382 + }
287 383
288 - $results = $wpdb->get_results("SELECT * FROM ".$wpdb->prefix."signups WHERE active = 0");
384 + $results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM ".$wpdb->base_prefix."signups WHERE $where ORDER BY $orderby $order LIMIT %d, %d", $offset, $per_page ) );
385 +
289 386 foreach ($results as $result){
290 - $tempArray = array('ID' => $result->user_email, 'username' => $result->user_login, 'email' => $result->user_email, 'registered' => $result->registered);
387 + $tempArray = array('ID' => $result->user_email, 'username' => $result->user_login, 'email' => $result->user_email, 'registered' => $result->registered);
388 + array_push($this->dataArray, $tempArray);
389 + }
291 390
292 - array_push($this->dataArray, $tempArray);
293 - $iterator++;
294 - }
295 -
296 391 /**
297 - * First, lets decide how many records per page to show
392 + * REQUIRED for pagination. Let's check how many items are in our data array.
393 + * In real-world use, this would be the total number of items in your database,
394 + * without filtering. We'll need this later, so you should always include it
395 + * in your own package classes.
298 396 */
299 - $per_page = apply_filters('wppb_email_confirmation_user_per_page_number', 20);
397 + $total_items = $wpdb->get_var( "SELECT COUNT(*) FROM ".$wpdb->base_prefix."signups WHERE $where" );
300 398
301 -
302 399 /**
303 400 * REQUIRED. Now we need to define our column headers. This includes a complete
304 401 * array of columns to be displayed (slugs & titles), a list of columns
305 402 * to keep hidden, and a list of columns that are sortable. Each of these
@@ -336,52 +433,10 @@
336 433 * use sort and pagination data to build a custom query instead, as you'll
337 434 * be able to use your precisely-queried data immediately.
338 435 */
339 436 $data = $this->dataArray;
340 -
341 -
342 - /**
343 - * This checks for sorting input and sorts the data in our array accordingly.
344 - *
345 - * In a real-world situation involving a database, you would probably want
346 - * to handle sorting by passing the 'orderby' and 'order' values directly
347 - * to a custom query. The returned data will be pre-sorted, and this array
348 - * sorting technique would be unnecessary.
349 - */
350 - function usort_reorder($a,$b){
351 - $orderby = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : 'username'; //If no sort, default to username
352 - $order = (!empty($_REQUEST['order'])) ? $_REQUEST['order'] : 'asc'; //If no order, default to asc
353 - $result = strcmp($a[$orderby], $b[$orderby]); //Determine sort order
354 - return ($order==='asc') ? $result : -$result; //Send final sort direction to usort
355 - }
356 - usort($data, 'usort_reorder');
357 437
358 438 /**
359 - * REQUIRED for pagination. Let's figure out what page the user is currently
360 - * looking at. We'll need this later, so you should always include it in
361 - * your own package classes.
362 - */
363 - $current_page = $this->get_pagenum();
364 -
365 - /**
366 - * REQUIRED for pagination. Let's check how many items are in our data array.
367 - * In real-world use, this would be the total number of items in your database,
368 - * without filtering. We'll need this later, so you should always include it
369 - * in your own package classes.
370 - */
371 - $total_items = count($data);
372 -
373 -
374 - /**
375 - * The PB_WP_List_Table class does not handle pagination for us, so we need
376 - * to ensure that the data is trimmed to only the current page. We can use
377 - * array_slice() to
378 - */
379 - $data = array_slice($data,(($current_page-1)*$per_page),$per_page);
380 -
381 -
382 -
383 - /**
384 439 * REQUIRED. Now we can add our *sorted* data to the items property, where
385 440 * it can be used by the rest of the class.
386 441 */
387 442 $this->items = $data;
@@ -407,19 +462,16 @@
407 462 *******************************************************************************
408 463 * Now we just need to define an admin page.
409 464 */
410 465 function wppb_add_ec_submenu_page() {
411 - if (is_multisite()){
412 - add_submenu_page( 'users.php', 'Unconfirmed Email Address', 'Unconfirmed Email Address', 'manage_options', 'unconfirmed_emails', 'wppb_unconfirmed_email_address_custom_menu_page' );
413 - remove_submenu_page( 'users.php', 'unconfirmed_emails' ); //hide the page in the admin menu
414 -
415 - }else{
416 - $wppb_generalSettings = get_option('wppb_general_settings', 'not_found');
417 - if($wppb_generalSettings != 'not_found')
418 - if(!empty($wppb_generalSettings['emailConfirmation']) && ($wppb_generalSettings['emailConfirmation'] == 'yes'))
419 - add_submenu_page( 'users.php', 'Unconfirmed Email Address', 'Unconfirmed Email Address', 'manage_options', 'unconfirmed_emails', 'wppb_unconfirmed_email_address_custom_menu_page' );
420 - remove_submenu_page( 'users.php', 'unconfirmed_emails' ); //hide the page in the admin menu
421 - }
466 + $wppb_generalSettings = get_option('wppb_general_settings', 'not_found');
467 + if($wppb_generalSettings != 'not_found') {
468 + if( !empty($wppb_generalSettings['emailConfirmation']) && ($wppb_generalSettings['emailConfirmation'] == 'yes') ){
469 + $hook = add_submenu_page('users.php', 'Unconfirmed Email Address', 'Unconfirmed Email Address', 'manage_options', 'unconfirmed_emails', 'wppb_unconfirmed_email_address_custom_menu_page');
470 + add_action( "load-$hook", 'wppb_ec_screen_options' ); //add screen options to Unconfirmed Email Users page
471 + //remove_submenu_page('users.php', 'unconfirmed_emails'); //hide the page in the admin menu
472 + }
473 + }
422 474 }
423 475 add_action('admin_menu', 'wppb_add_ec_submenu_page');
424 476
425 477
@@ -432,9 +484,9 @@
432 484 * so we've instead called those methods explicitly. It keeps things flexible, and
433 485 * it's the way the list tables are used in the WordPress core.
434 486 */
435 487 function wppb_unconfirmed_email_address_custom_menu_page(){
436 -
488 +
437 489 //Create an instance of our package class...
438 490 $listTable = new wpp_list_unfonfirmed_email_table();
439 491 //Fetch, prepare, sort, and filter our data...
440 492 $listTable->prepare_items();
@@ -441,18 +493,19 @@
441 493
442 494 ?>
443 495 <div class="wrap">
444 496
445 - <div class="wrap"><div id="icon-users" class="icon32"></div><h2><?php _e('Users with Unconfirmed Email Address', 'profilebuilder');?></h2></div>
497 + <div class="wrap"><div id="icon-users" class="icon32"></div><h2><?php esc_html_e('Users with Unconfirmed Email Address', 'profile-builder');?></h2></div>
446 498
447 499 <ul class="subsubsub">
448 - <li class="all"><a href="users.php"><?php _e('All Users', 'profilebuilder');?></a></li>
500 + <li class="all"><a href="users.php"><?php esc_html_e('All Users', 'profile-builder');?></a></li>
449 501 </ul>
450 502
451 503 <!-- Forms are NOT created automatically, so you need to wrap the table in one to use features like bulk actions -->
452 504 <form id="movies-filter" method="get">
453 505 <!-- For plugins, we also need to ensure that the form posts back to our current page -->
454 - <input type="hidden" name="page" value="<?php echo $_REQUEST['page'] ?>" />
506 + <?php $listTable->search_box( __( 'Search Users', 'profile-builder' ), 'user' ); ?>
507 + <input type="hidden" name="page" value="<?php echo isset( $_REQUEST['page'] ) ? esc_attr( sanitize_text_field( $_REQUEST['page'] ) ) : ''; ?>" />
455 508 <!-- Now we can render the completed list table -->
456 509 <?php $listTable->display() ?>
457 510 </form>
458 511
@@ -457,5 +510,32 @@
457 510 </form>
458 511
459 512 </div>
460 513 <?php
514 +}
515 +
516 +/**
517 + * Function that handles the screen options on Unconfirmed Email Users page
518 + */
519 +function wppb_ec_screen_options(){
520 + $option = 'per_page';
521 +
522 + $args = array(
523 + 'label' => __( 'Number of items per page:' , 'profile-builder' ),//use the default wordpress domain
524 + 'default' => 20,
525 + 'option' => 'users_per_page' //this is the same option as the one on the normal User screen
526 + );
527 +
528 + add_screen_option( $option, $args );
529 +}
530 +
531 +/**
532 + * Fix the page title of the admin page, since using remove_sumbenu_page() breaks the page title
533 + */
534 +add_filter('admin_title', 'wppb_ec_admin_title', 10 );
535 +function wppb_ec_admin_title($admin_title){
536 + if( isset( $_GET['page'] ) && sanitize_text_field( $_GET['page'] ) === 'unconfirmed_emails' ) {
537 + $admin_title = __('Users with Unconfirmed Email Address', 'profile-builder') . $admin_title;
538 + }
539 +
540 + return $admin_title;
461 541 }