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 +60 -27 3.9.6 → 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
@@ -72,9 +75,9 @@
72 75 **************************************************************************/
73 76 function column_default($item, $column_name){
74 77 switch($column_name){
75 78 case 'email':
76 - return $item[$column_name];
79 + return esc_html( $item[$column_name] );
77 80 case 'registered':
78 81 return date_i18n( "Y-m-d G:i:s", wppb_add_gmt_offset( strtotime( $item[$column_name] ) ) );
79 82 case 'user-meta':
80 83 global $wpdb;
@@ -79,18 +82,23 @@
79 82 case 'user-meta':
80 83 global $wpdb;
81 84 $sql_result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE user_email = %s", $item['email'] ), ARRAY_A );
82 85 $user_meta = $sql_result['meta'];
83 - $user_meta_content = '';
84 - if( !empty( $user_meta ) ){
85 - foreach( maybe_unserialize( $user_meta ) as $key => $value ){
86 - if( $key != 'user_pass' ){
87 - if ( is_array($value) ) $value = implode(',',$value);
88 - $user_meta_content .= $key.':'.$value.'<br/>';
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;
89 91 }
92 + if ( is_array( $value ) ) {
93 + $value = implode( ',', $value );
94 + }
95 + $user_meta_lines[] = esc_html( (string) $key ) . ':' . esc_html( (string) $value );
90 96 }
91 97 }
92 - return '<a href="#" data-email="'. $item['email'] .'" onclick="'. esc_attr( 'jQuery(\'<div><pre>'. $user_meta_content .'</pre></div>\').dialog({title:\''. addslashes( __("User Meta", "profile-builder" ) ) .'\', width: 500 }) ;return false;') .'">'. __( 'show', 'profile-builder' ) .'</a>';
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>';
93 101 default:
94 102 return print_r($item,true); //Show the whole array for troubleshooting purposes
95 103 }
96 104 }
@@ -95,8 +103,22 @@
95 103 }
96 104 }
97 105
98 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 +
99 121 /** ************************************************************************
100 122 * Recommended. This is a custom column method and is responsible for what
101 123 * is rendered in any column with a name/slug of 'username'. Every time the class
102 124 * needs to render a column, it first looks for a method named
@@ -111,23 +133,24 @@
111 133 * @see PB_WP_List_Table::::single_row_columns()
112 134 * @param array $item A singular item (one full row's worth of data)
113 135 * @return string Text to be placed inside the column <td>
114 136 **************************************************************************/
115 - function column_username($item){
137 + function column_username( $item ) {
116 138
117 139 $GRavatar = get_avatar( $item['email'], 32, '' );
118 -
119 - //Build row actions
140 + $current_url = wppb_curpageurl();
141 + $email = $item['ID'];
142 +
120 143 $actions = array(
121 - 'delete' => sprintf( '<a href="javascript:confirmECAction( \'%s\', \'%s\', \'%s\', \'' . addslashes( __( 'delete this user from the _signups table?', 'profile-builder' ) ) . '\' )">' . __( 'Delete', 'profile-builder' ) . '</a>', wppb_curpageurl(), 'delete', $item['ID'] ),
122 - 'confirm' => sprintf( '<a href="javascript:confirmECAction( \'%s\', \'%s\', \'%s\', \'' . addslashes( __( 'confirm this email yourself?', 'profile-builder' ) ) . '\' )">' . __( 'Confirm Email', 'profile-builder' ) . '</a>', wppb_curpageurl(), 'confirm', $item['ID'] ),
123 - 'resend' => sprintf( '<a href="javascript:confirmECAction( \'%s\', \'%s\', \'%s\', \'' . addslashes( __( 'resend the activation link?', 'profile-builder' ) ) . '\' )">' . __( 'Resend Activation Email', 'profile-builder' ) . '</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' ) ),
124 147 );
125 148
126 149 //Return the user row
127 150 return sprintf('%1$s <strong>%2$s</strong> %3$s',
128 151 /*$1%s*/ $GRavatar,
129 - /*$2%s*/ $item['username'],
152 + /*$2%s*/ esc_html( $item['username'] ),
130 153 /*$3%s*/ $this->row_actions($actions)
131 154 );
132 155 }
133 156
@@ -142,10 +165,10 @@
142 165 **************************************************************************/
143 166 function column_cb($item){
144 167 return sprintf(
145 168 '<input type="checkbox" name="%1$s[]" value="%2$s" />',
146 - /*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label
147 - /*$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'] )
148 171 );
149 172 }
150 173
151 174
@@ -239,9 +262,16 @@
239 262
240 263 function wppb_process_bulk_action() {
241 264 global $current_user;
242 265 global $wpdb;
243 -
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 +
244 274 if ( current_user_can( apply_filters( 'wppb_email_confirmation_user_capability', 'manage_options' ) ) ){
245 275 if( 'delete' === $this->current_action() ) {
246 276 if( !empty( $_GET['user'] ) && is_array( $_GET['user'] ) ) {
247 277 foreach ( array_map( 'sanitize_email', $_GET['user'] ) as $user) {
@@ -247,9 +277,9 @@
247 277 foreach ( array_map( 'sanitize_email', $_GET['user'] ) as $user) {
248 278 $sql_result = $wpdb->query($wpdb->prepare("DELETE FROM " . $wpdb->base_prefix . "signups WHERE user_email = %s", $user));
249 279
250 280 if (!$sql_result)
251 - $this->wppb_process_bulk_action_message(sprintf(__("%s couldn't be deleted", "profile-builder"), $result->user_login), get_bloginfo('url') . '/wp-admin/users.php?page=unconfirmed_emails');
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');
252 282
253 283 }
254 284 }
255 285
@@ -323,17 +353,20 @@
323 353 $offset = 0;
324 354
325 355 /* handle order and orderby attr */
326 356 if( !empty( $_REQUEST['orderby'] ) ){
357 +
327 358 $orderby = sanitize_sql_orderby( $_REQUEST['orderby'] );
359 +
328 360 if( $orderby == 'username' )
329 361 $orderby = 'user_login';
330 362 elseif ( $orderby == 'email' )
331 363 $orderby = 'user_email';
332 - }
333 - else
364 +
365 + } else
334 366 $orderby = 'user_login';
335 - if( !empty( $_REQUEST['order'] ) && $_REQUEST['order'] === 'desc' )
367 +
368 + if( !empty( $_REQUEST['order'] ) && sanitize_text_field( $_REQUEST['order'] ) === 'desc' )
336 369 $order = "DESC";
337 370 else
338 371 $order = 'ASC';
339 372
@@ -344,12 +377,12 @@
344 377 }
345 378 /* since version 2.0.7 for multisite we add a 'registered_for_blog_id' meta in the registration process
346 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 */
347 380 if( is_multisite() ){
348 - $where .= " AND ( meta NOT LIKE '%\"registered_for_blog_id\"%' OR meta LIKE '%\"registered_for_blog_id\";i:".get_current_blog_id()."%' )";
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().'%' );
349 382 }
350 383
351 - $results = $wpdb->get_results("SELECT * FROM ".$wpdb->base_prefix."signups WHERE $where ORDER BY $orderby $order LIMIT $offset, $per_page");
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 ) );
352 385
353 386 foreach ($results as $result){
354 387 $tempArray = array('ID' => $result->user_email, 'username' => $result->user_login, 'email' => $result->user_email, 'registered' => $result->registered);
355 388 array_push($this->dataArray, $tempArray);
@@ -360,9 +393,9 @@
360 393 * In real-world use, this would be the total number of items in your database,
361 394 * without filtering. We'll need this later, so you should always include it
362 395 * in your own package classes.
363 396 */
364 - $total_items = $wpdb->get_var("SELECT COUNT(*) FROM ".$wpdb->base_prefix."signups WHERE $where");
397 + $total_items = $wpdb->get_var( "SELECT COUNT(*) FROM ".$wpdb->base_prefix."signups WHERE $where" );
365 398
366 399 /**
367 400 * REQUIRED. Now we need to define our column headers. This includes a complete
368 401 * array of columns to be displayed (slugs & titles), a list of columns
@@ -434,9 +467,9 @@
434 467 if($wppb_generalSettings != 'not_found') {
435 468 if( !empty($wppb_generalSettings['emailConfirmation']) && ($wppb_generalSettings['emailConfirmation'] == 'yes') ){
436 469 $hook = add_submenu_page('users.php', 'Unconfirmed Email Address', 'Unconfirmed Email Address', 'manage_options', 'unconfirmed_emails', 'wppb_unconfirmed_email_address_custom_menu_page');
437 470 add_action( "load-$hook", 'wppb_ec_screen_options' ); //add screen options to Unconfirmed Email Users page
438 - remove_submenu_page('users.php', 'unconfirmed_emails'); //hide the page in the admin menu
471 + //remove_submenu_page('users.php', 'unconfirmed_emails'); //hide the page in the admin menu
439 472 }
440 473 }
441 474 }
442 475 add_action('admin_menu', 'wppb_add_ec_submenu_page');
@@ -451,9 +484,9 @@
451 484 * so we've instead called those methods explicitly. It keeps things flexible, and
452 485 * it's the way the list tables are used in the WordPress core.
453 486 */
454 487 function wppb_unconfirmed_email_address_custom_menu_page(){
455 -
488 +
456 489 //Create an instance of our package class...
457 490 $listTable = new wpp_list_unfonfirmed_email_table();
458 491 //Fetch, prepare, sort, and filter our data...
459 492 $listTable->prepare_items();