Ticket #8448: 8448.4.patch
File 8448.4.patch, 68.1 KB (added by , 4 years ago) |
---|
-
src/bp-core/admin/bp-core-admin-functions.php
diff --git src/bp-core/admin/bp-core-admin-functions.php src/bp-core/admin/bp-core-admin-functions.php index b81786427..7749dd449 100644
function bp_core_modify_admin_menu_highlight() { 84 84 if ( in_array( $plugin_page, array( 'bp-tools', 'available-tools' ) ) ) { 85 85 $submenu_file = $plugin_page; 86 86 } 87 88 // Keep the BuddyPress tools menu highlighted. 89 if ( 'bp-optouts' === $plugin_page ) { 90 $submenu_file = 'bp-tools'; 91 } 87 92 } 88 93 89 94 /** … … function bp_do_activation_redirect() { 389 394 * Output the tabs in the admin area. 390 395 * 391 396 * @since 1.5.0 397 * @since 8.0.0 Adds the `$context` parameter. 392 398 * 393 399 * @param string $active_tab Name of the tab that is active. Optional. 400 * @param string $context The context of use for the tabs. Defaults to 'settings'. 401 * Possible values are 'settings' & 'tools'. 394 402 */ 395 function bp_core_admin_tabs( $active_tab = '' ) {403 function bp_core_admin_tabs( $active_tab = '', $context = 'settings' ) { 396 404 $tabs_html = ''; 397 405 $idle_class = 'nav-tab'; 398 406 $active_class = 'nav-tab nav-tab-active'; … … function bp_core_admin_tabs( $active_tab = '' ) { 404 412 * 405 413 * @param array $value Array of tabs to output to the admin area. 406 414 */ 407 $tabs = apply_filters( 'bp_core_admin_tabs', bp_core_get_admin_tabs( $active_tab ) );415 $tabs = apply_filters( 'bp_core_admin_tabs', bp_core_get_admin_tabs( $active_tab, $context ) ); 408 416 409 417 // Loop through tabs and build navigation. 410 418 foreach ( array_values( $tabs ) as $tab_data ) { … … function bp_core_admin_tabs( $active_tab = '' ) { 419 427 * Fires after the output of tabs for the admin area. 420 428 * 421 429 * @since 1.5.0 430 * @since 8.0.0 Adds the `$context` parameter. 431 * 432 * @param string $context The context of use for the tabs. 422 433 */ 423 do_action( 'bp_admin_tabs' );434 do_action( 'bp_admin_tabs', $context ); 424 435 } 425 436 426 437 /** 427 438 * Get the data for the tabs in the admin area. 428 439 * 429 440 * @since 2.2.0 441 * @since 8.0.0 Adds the `$context` parameter. 430 442 * 431 443 * @param string $active_tab Name of the tab that is active. Optional. 444 * @param string $context The context of use for the tabs. Defaults to 'settings'. 445 * Possible values are 'settings' & 'tools'. 432 446 * @return string 433 447 */ 434 function bp_core_get_admin_tabs( $active_tab = '' ) { 435 $tabs = array( 436 '0' => array( 437 'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components' ), 'admin.php' ) ), 438 'name' => __( 'Components', 'buddypress' ), 439 ), 440 '2' => array( 441 'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-settings' ), 'admin.php' ) ), 442 'name' => __( 'Options', 'buddypress' ), 443 ), 444 '1' => array( 445 'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) ), 446 'name' => __( 'Pages', 'buddypress' ), 447 ), 448 '3' => array( 449 'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-credits' ), 'admin.php' ) ), 450 'name' => __( 'Credits', 'buddypress' ), 451 ), 452 ); 448 function bp_core_get_admin_tabs( $active_tab = '', $context = 'settings' ) { 449 $tabs = array(); 450 451 if ( 'settings' === $context ) { 452 $tabs = array( 453 '0' => array( 454 'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components' ), 'admin.php' ) ), 455 'name' => __( 'Components', 'buddypress' ), 456 ), 457 '2' => array( 458 'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-settings' ), 'admin.php' ) ), 459 'name' => __( 'Options', 'buddypress' ), 460 ), 461 '1' => array( 462 'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) ), 463 'name' => __( 'Pages', 'buddypress' ), 464 ), 465 '3' => array( 466 'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-credits' ), 'admin.php' ) ), 467 'name' => __( 'Credits', 'buddypress' ), 468 ), 469 ); 470 } elseif ( 'tools' === $context ) { 471 $tools_page = 'tools.php'; 472 if ( bp_core_do_network_admin() ) { 473 $tools_page = 'admin.php'; 474 } 475 476 $tabs = array( 477 '0' => array( 478 'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-tools' ), $tools_page ) ), 479 'name' => __( 'Repair', 'buddypress' ), 480 ), 481 '1' => array( 482 'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-optouts' ), $tools_page ) ), 483 'name' => __( 'Manage Opt-outs', 'buddypress' ), 484 ), 485 ); 486 } 453 487 454 488 /** 455 489 * Filters the tab data used in our wp-admin screens. 456 490 * 457 491 * @since 2.2.0 492 * @since 8.0.0 Adds the `$context` parameter. 458 493 * 459 * @param array $tabs Tab data. 494 * @param array $tabs Tab data. 495 * @param string $context The context of use for the tabs. 460 496 */ 461 return apply_filters( 'bp_core_get_admin_tabs', $tabs );497 return apply_filters( 'bp_core_get_admin_tabs', $tabs, $context ); 462 498 } 463 499 464 500 /** Help **********************************************************************/ -
new file src/bp-core/admin/bp-core-admin-optouts.php
diff --git src/bp-core/admin/bp-core-admin-optouts.php src/bp-core/admin/bp-core-admin-optouts.php new file mode 100644 index 000000000..68fcf3c3c
- + 1 <?php 2 /** 3 * BuddyPress Opt-outs management. 4 * 5 * @package BuddyPress 6 * @subpackage Core 7 * @since 8.0.0 8 */ 9 10 // Exit if accessed directly. 11 defined( 'ABSPATH' ) || exit; 12 13 /** 14 * Set up the Opt-outs admin page. 15 * 16 * Loaded before the page is rendered, this function does all initial 17 * setup, including: processing form requests, registering contextual 18 * help, and setting up screen options. 19 * 20 * @since 8.0.0 21 * 22 * @global $bp_optouts_list_table 23 */ 24 function bp_core_optouts_admin_load() { 25 global $bp_optouts_list_table; 26 27 // Build redirection URL. 28 $redirect_to = remove_query_arg( array( 'action', 'error', 'updated', 'activated', 'notactivated', 'deleted', 'notdeleted', 'resent', 'notresent', 'do_delete', 'do_resend', 'do_activate', '_wpnonce', 'signup_ids' ), $_SERVER['REQUEST_URI'] ); 29 $doaction = bp_admin_list_table_current_bulk_action(); 30 31 /** 32 * Fires at the start of the nonmember opt-outs admin load. 33 * 34 * @since 8.0.0 35 * 36 * @param string $doaction Current bulk action being processed. 37 * @param array $_REQUEST Current $_REQUEST global. 38 */ 39 do_action( 'bp_optouts_admin_load', $doaction, $_REQUEST ); 40 41 /** 42 * Filters the allowed actions for use in the nonmember optouts admin page. 43 * 44 * @since 8.0.0 45 * 46 * @param array $value Array of allowed actions to use. 47 */ 48 $allowed_actions = apply_filters( 'bp_optouts_admin_allowed_actions', array( 'do_delete', 'do_resend' ) ); 49 50 if ( ! in_array( $doaction, $allowed_actions ) || ( -1 == $doaction ) ) { 51 52 require_once( ABSPATH . 'wp-admin/includes/class-wp-users-list-table.php' ); 53 $bp_optouts_list_table = new BP_Optouts_List_Table(); 54 55 // The per_page screen option. 56 add_screen_option( 'per_page', array( 'label' => _x( 'Nonmember opt-outs', 'Nonmember opt-outs per page (screen options)', 'buddypress' ) ) ); 57 58 // Current screen. 59 $current_screen = get_current_screen(); 60 61 $current_screen->add_help_tab( 62 array( 63 'id' => 'bp-optouts-overview', 64 'title' => __( 'Overview', 'buddypress' ), 65 'content' => 66 '<p>' . __( 'This is the administration screen for nonmember opt-outs on your site.', 'buddypress' ) . '</p>' . 67 '<p>' . __( 'From the screen options, you can customize the displayed columns and the pagination of this screen.', 'buddypress' ) . '</p>' . 68 '<p>' . __( 'You can reorder the list of opt-outs by clicking on the Email Sender, Email Type or Date Modified column headers.', 'buddypress' ) . '</p>' . 69 '<p>' . __( 'Using the search form, you can search for an opt-out to a specific email address.', 'buddypress' ) . '</p>', 70 ) 71 ); 72 73 $current_screen->add_help_tab( 74 array( 75 'id' => 'bp-optouts-actions', 76 'title' => __( 'Actions', 'buddypress' ), 77 'content' => 78 '<p>' . __( 'Hovering over a row in the opt-outs list will display action links that allow you to manage the opt-out. You can perform the following actions:', 'buddypress' ) . '</p>' . 79 '<ul><li>' . __( '"Delete" allows you to delete the record of an opt-out. You will be asked to confirm this deletion.', 'buddypress' ) . '</li></ul>' . 80 '<p>' . __( 'Bulk actions allow you to perform these actions for the selected rows.', 'buddypress' ) . '</p>', 81 ) 82 ); 83 84 // Help panel - sidebar links. 85 $current_screen->set_help_sidebar( 86 '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' . 87 '<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>' 88 ); 89 90 // Add accessible hidden headings and text for the Pending Users screen. 91 $current_screen->set_screen_reader_content( 92 array( 93 /* translators: accessibility text */ 94 'heading_views' => __( 'Filter opt-outs list', 'buddypress' ), 95 /* translators: accessibility text */ 96 'heading_pagination' => __( 'Opt-out list navigation', 'buddypress' ), 97 /* translators: accessibility text */ 98 'heading_list' => __( 'Opt-outs list', 'buddypress' ), 99 ) 100 ); 101 102 } else { 103 if ( empty( $_REQUEST['optout_ids' ] ) ) { 104 return; 105 } 106 $optout_ids = wp_parse_id_list( $_REQUEST['optout_ids' ] ); 107 108 // Handle optout deletion. 109 if ( 'do_delete' == $doaction ) { 110 111 // Nonce check. 112 check_admin_referer( 'optouts_delete' ); 113 114 $success = 0; 115 foreach ( $optout_ids as $optout_id ) { 116 if ( bp_delete_optout_by_id( $optout_id ) ) { 117 $success++; 118 } 119 } 120 121 $query_arg = array( 'updated' => 'deleted' ); 122 123 if ( ! empty( $success ) ) { 124 $query_arg['deleted'] = $success; 125 } 126 127 $notdeleted = count( $optout_ids ) - $success; 128 if ( $notdeleted > 0 ) { 129 $query_arg['notdeleted'] = $notdeleted; 130 } 131 132 $redirect_to = add_query_arg( $query_arg, $redirect_to ); 133 134 bp_core_redirect( $redirect_to ); 135 136 // Plugins can update other stuff from here. 137 } else { 138 139 /** 140 * Fires at end of opt-outs admin load 141 * if doaction does not match any actions. 142 * 143 * @since 2.0.0 144 * 145 * @param string $doaction Current bulk action being processed. 146 * @param array $_REQUEST Current $_REQUEST global. 147 * @param string $redirect Determined redirect url to send user to. 148 */ 149 do_action( 'bp_core_admin_update_optouts', $doaction, $_REQUEST, $redirect_to ); 150 151 bp_core_redirect( $redirect_to ); 152 } 153 } 154 } 155 add_action( "load-tools_page_bp-optouts", 'bp_core_optouts_admin_load' ); 156 157 /** 158 * Get admin notice when viewing the optouts management page. 159 * 160 * @since 8.0.0 161 * 162 * @return array 163 */ 164 function bp_core_get_optouts_notice() { 165 166 // Setup empty notice for return value. 167 $notice = array(); 168 169 // Updates. 170 if ( ! empty( $_REQUEST['updated'] ) && 'deleted' === $_REQUEST['updated'] ) { 171 $notice = array( 172 'class' => 'updated', 173 'message' => '' 174 ); 175 176 if ( ! empty( $_REQUEST['deleted'] ) ) { 177 $notice['message'] .= sprintf( 178 /* translators: %s: number of deleted optouts */ 179 _nx( '%s opt-out successfully deleted!', '%s opt-outs successfully deleted!', 180 absint( $_REQUEST['deleted'] ), 181 'nonmembers optout deleted', 182 'buddypress' 183 ), 184 number_format_i18n( absint( $_REQUEST['deleted'] ) ) 185 ); 186 } 187 188 if ( ! empty( $_REQUEST['notdeleted'] ) ) { 189 $notice['message'] .= sprintf( 190 /* translators: %s: number of optouts that failed to be deleted */ 191 _nx( '%s opt-out was not deleted.', '%s opt-outs were not deleted.', 192 absint( $_REQUEST['notdeleted'] ), 193 'nonmembers optout not deleted', 194 'buddypress' 195 ), 196 number_format_i18n( absint( $_REQUEST['notdeleted'] ) ) 197 ); 198 199 if ( empty( $_REQUEST['deleted'] ) ) { 200 $notice['class'] = 'error'; 201 } 202 } 203 } 204 205 // Errors. 206 if ( ! empty( $_REQUEST['error'] ) && 'do_delete' === $_REQUEST['error'] ) { 207 $notice = array( 208 'class' => 'error', 209 'message' => esc_html__( 'There was a problem deleting opt-outs. Please try again.', 'buddypress' ), 210 ); 211 } 212 213 return $notice; 214 } 215 216 /** 217 * Opt-outs admin page router. 218 * 219 * Depending on the context, display 220 * - the list of optouts, 221 * - or the delete confirmation screen, 222 * 223 * Also prepare the admin notices. 224 * 225 * @since 8.0.0 226 */ 227 function bp_core_optouts_admin() { 228 $doaction = bp_admin_list_table_current_bulk_action(); 229 230 // Prepare notices for admin. 231 $notice = bp_core_get_optouts_notice(); 232 233 // Display notices. 234 if ( ! empty( $notice ) ) : 235 if ( 'updated' === $notice['class'] ) : ?> 236 237 <div id="message" class="<?php echo esc_attr( $notice['class'] ); ?> notice is-dismissible"> 238 239 <?php else: ?> 240 241 <div class="<?php echo esc_attr( $notice['class'] ); ?> notice is-dismissible"> 242 243 <?php endif; ?> 244 245 <p><?php echo esc_html( $notice['message'] ); ?></p> 246 </div> 247 248 <?php endif; 249 250 // Show the proper screen. 251 switch ( $doaction ) { 252 case 'delete' : 253 bp_core_optouts_admin_manage( $doaction ); 254 break; 255 256 default: 257 bp_core_optouts_admin_index(); 258 break; 259 } 260 } 261 262 /** 263 * This is the list of optouts. 264 * 265 * @since 8.0.0 266 * 267 * @global $plugin_page 268 * @global $bp_optouts_list_table 269 */ 270 function bp_core_optouts_admin_index() { 271 global $plugin_page, $bp_optouts_list_table; 272 273 $usersearch = ! empty( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : ''; 274 275 // Prepare the group items for display. 276 $bp_optouts_list_table->prepare_items(); 277 278 if ( is_network_admin() ) { 279 $form_url = network_admin_url( 'admin.php' ); 280 } else { 281 $form_url = bp_get_admin_url( 'tools.php' ); 282 } 283 284 $form_url = add_query_arg( 285 array( 286 'page' => 'bp-optouts', 287 ), 288 $form_url 289 ); 290 291 $search_form_url = remove_query_arg( 292 array( 293 'action', 294 'deleted', 295 'notdeleted', 296 'error', 297 'updated', 298 'delete', 299 'activate', 300 'activated', 301 'notactivated', 302 'resend', 303 'resent', 304 'notresent', 305 'do_delete', 306 'do_activate', 307 'do_resend', 308 'action2', 309 '_wpnonce', 310 'optout_ids' 311 ), 312 $_SERVER['REQUEST_URI'] 313 ); 314 315 ?> 316 317 <div class="wrap"> 318 <h1 class="wp-heading-inline"><?php esc_html_e( 'BuddyPress tools', 'buddypress' ); ?></h1> 319 <hr class="wp-header-end"> 320 321 <h2 class="nav-tab-wrapper"><?php bp_core_admin_tabs( __( 'Manage Opt-outs', 'buddypress' ), 'tools' ); ?></h2> 322 323 <?php 324 if ( $usersearch ) { 325 $num_results = (int) $bp_optouts_list_table->total_items; 326 printf( '<p><span class="subtitle">' . esc_html( _n( 'Opt-out with an email address matching “%s”', 'Opt-outs with an email address matching “%s”', $num_results, 'buddypress' ) ) . '</span></p>', esc_html( $usersearch ) ); 327 } 328 ?> 329 <p><?php esc_html_e( 'This table shows opt-out requests from people who are not members of this site, but have been contacted via communication from this site, and wish to receive no further communications.', 'buddypress' ); ?></p> 330 331 <?php // Display each opt-out on its own row. ?> 332 <?php $bp_optouts_list_table->views(); ?> 333 334 <form id="bp-optouts-search-form" action="<?php echo esc_url( $search_form_url ) ;?>"> 335 <input type="hidden" name="page" value="<?php echo esc_attr( $plugin_page ); ?>" /> 336 <?php $bp_optouts_list_table->search_box( esc_html__( 'Search for a specific email address', 'buddypress' ), 'bp-optouts' ); ?> 337 </form> 338 339 <form id="bp-optouts-form" action="<?php echo esc_url( $form_url );?>" method="post"> 340 <?php $bp_optouts_list_table->display(); ?> 341 </form> 342 </div> 343 <?php 344 } 345 346 /** 347 * This is the confirmation screen for actions. 348 * 349 * @since 8.0.0 350 * 351 * @param string $action Delete or resend optout. 352 * 353 * @return null|false 354 */ 355 function bp_core_optouts_admin_manage( $action = '' ) { 356 $capability = bp_core_do_network_admin() ? 'manage_network_options' : 'manage_options'; 357 if ( ! current_user_can( $capability ) || empty( $action ) ) { 358 die( '-1' ); 359 } 360 361 // Get the IDs from the URL. 362 $ids = false; 363 if ( ! empty( $_POST['optout_ids'] ) ) { 364 $ids = wp_parse_id_list( $_POST['optout_ids'] ); 365 } elseif ( ! empty( $_GET['optout_id'] ) ) { 366 $ids = absint( $_GET['optout_id'] ); 367 } 368 369 if ( empty( $ids ) ) { 370 return false; 371 } 372 373 // Query for matching optouts, and filter out bad IDs. 374 $args = array( 375 'id' => $ids, 376 ); 377 $optouts = bp_get_optouts( $args ); 378 $optout_ids = wp_list_pluck( $optouts, 'id' ); 379 380 // Check optout IDs and set up strings. 381 switch ( $action ) { 382 case 'delete' : 383 if ( 1 == count( $optouts ) ) { 384 $helper_text = __( 'You are about to delete the following opt-out request:', 'buddypress' ); 385 } else { 386 $helper_text = __( 'You are about to delete the following opt-out requests:', 'buddypress' ); 387 } 388 break; 389 } 390 391 // These arguments are added to all URLs. 392 $url_args = array( 'page' => 'bp-optouts' ); 393 394 // These arguments are only added when performing an action. 395 $action_args = array( 396 'action' => 'do_' . $action, 397 'optout_ids' => implode( ',', $optout_ids ) 398 ); 399 400 if ( is_network_admin() ) { 401 $base_url = network_admin_url( 'admin.php' ); 402 } else { 403 $base_url = bp_get_admin_url( 'tools.php' ); 404 } 405 406 $cancel_url = add_query_arg( $url_args, $base_url ); 407 $action_url = wp_nonce_url( 408 add_query_arg( 409 array_merge( $url_args, $action_args ), 410 $base_url 411 ), 412 'optouts_' . $action 413 ); 414 415 ?> 416 417 <div class="wrap"> 418 <h1 class="wp-heading-inline"><?php esc_html_e( 'BuddyPress tools', 'buddypress' ); ?></h1> 419 <hr class="wp-header-end"> 420 421 <h2 class="nav-tab-wrapper"><?php bp_core_admin_tabs( __( 'Manage Opt-outs', 'buddypress' ), 'tools' ); ?></h2> 422 423 <p><?php echo esc_html( $helper_text ); ?></p> 424 425 <ol class="bp-optouts-list"> 426 <?php foreach ( $optouts as $optout ) : ?> 427 428 <li> 429 <strong><?php echo esc_html( $optout->email_address ) ?></strong> 430 <p class="description"> 431 <?php 432 $last_modified = mysql2date( 'Y/m/d g:i:s a', $optout->date_modified ); 433 /* translators: %s: modification date */ 434 printf( esc_html__( 'Date modified: %s', 'buddypress'), $last_modified ); 435 ?> 436 </p> 437 </li> 438 439 <?php endforeach; ?> 440 </ol> 441 442 <?php if ( 'delete' === $action ) : ?> 443 444 <p><strong><?php esc_html_e( 'This action cannot be undone.', 'buddypress' ) ?></strong></p> 445 446 <?php endif ; ?> 447 448 <a class="button-primary" href="<?php echo esc_url( $action_url ); ?>"><?php esc_html_e( 'Confirm', 'buddypress' ); ?></a> 449 <a class="button" href="<?php echo esc_url( $cancel_url ); ?>"><?php esc_html_e( 'Cancel', 'buddypress' ) ?></a> 450 </div> 451 452 <?php 453 } -
src/bp-core/admin/bp-core-admin-schema.php
diff --git src/bp-core/admin/bp-core-admin-schema.php src/bp-core/admin/bp-core-admin-schema.php index 7a10e39eb..2dde95a4a 100644
function bp_core_install( $active_components = false ) { 40 40 // Install the invitations table. 41 41 bp_core_install_invitations(); 42 42 43 // Install the nonmember opt-outs table. 44 bp_core_install_nonmember_opt_outs(); 45 43 46 // Notifications. 44 47 if ( !empty( $active_components['notifications'] ) ) { 45 48 bp_core_install_notifications(); … … function bp_core_install_invitations() { 590 593 */ 591 594 do_action( 'bp_core_install_invitations' ); 592 595 } 596 597 /** 598 * Install database tables to store opt-out requests from nonmembers. 599 * 600 * @since 8.0.0 601 * 602 * @uses bp_core_set_charset() 603 * @uses bp_core_get_table_prefix() 604 * @uses dbDelta() 605 */ 606 function bp_core_install_nonmember_opt_outs() { 607 $sql = array(); 608 $charset_collate = $GLOBALS['wpdb']->get_charset_collate(); 609 $bp_prefix = bp_core_get_table_prefix(); 610 $optouts_class = new BP_Optout(); 611 $table_name = $optouts_class->get_table_name(); 612 $sql = "CREATE TABLE {$table_name} ( 613 id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, 614 email_address_hash varchar(255) NOT NULL, 615 user_id bigint(20) NOT NULL, 616 email_type varchar(255) NOT NULL, 617 date_modified datetime NOT NULL, 618 KEY user_id (user_id), 619 KEY email_type (email_type), 620 KEY date_modified (date_modified) 621 ) {$charset_collate};"; 622 dbDelta( $sql ); 623 624 /** 625 * Fires after BuddyPress adds the nonmember opt-outs table. 626 * 627 * @since 8.0.0 628 */ 629 do_action( 'bp_core_install_nonmember_opt_outs' ); 630 } -
src/bp-core/admin/bp-core-admin-tools.php
diff --git src/bp-core/admin/bp-core-admin-tools.php src/bp-core/admin/bp-core-admin-tools.php index 0d49c0d6f..8141eccbe 100644
function bp_core_admin_tools() { 22 22 <h1 class="wp-heading-inline"><?php esc_html_e( 'BuddyPress Tools', 'buddypress' ) ?></h1> 23 23 <hr class="wp-header-end"> 24 24 25 <h2 class="nav-tab-wrapper"><?php bp_core_admin_tabs( __( 'Repair', 'buddypress' ), 'tools' ); ?></h2> 26 25 27 <p><?php esc_html_e( 'BuddyPress keeps track of various relationships between members, groups, and activity items.', 'buddypress' ); ?></p> 26 28 <p><?php esc_html_e( 'Occasionally these relationships become out of sync, most often after an import, update, or migration.', 'buddypress' ); ?></p> 27 29 <p><?php esc_html_e( 'Use the tools below to manually recalculate these relationships.', 'buddypress' ); ?> … … function bp_core_admin_available_tools_intro() { 541 543 $page = bp_core_do_network_admin() ? 'admin.php' : 'tools.php' ; 542 544 $url = add_query_arg( $query_arg, bp_get_admin_url( $page ) ); 543 545 ?> 544 <div class="card tool-box ">546 <div class="card tool-box bp-tools"> 545 547 <h2><?php esc_html_e( 'BuddyPress Tools', 'buddypress' ) ?></h2> 546 <p> 547 <?php esc_html_e( 'BuddyPress keeps track of various relationships between users, groups, and activity items. Occasionally these relationships become out of sync, most often after an import, update, or migration.', 'buddypress' ); ?> 548 <?php 549 printf( 550 /* translators: %s: the link to the BuddyPress repair tools */ 551 esc_html_x( 'Use the %s to repair these relationships.', 'buddypress tools intro', 'buddypress' ), 552 '<a href="' . esc_url( $url ) . '">' . esc_html__( 'BuddyPress Tools', 'buddypress' ) . '</a>' 553 ); 554 ?> 555 </p> 548 549 <dl> 550 <dt><?php esc_html_e( 'Repair Tools', 'buddypress' ) ?></dt> 551 <dd> 552 <?php esc_html_e( 'BuddyPress keeps track of various relationships between users, groups, and activity items. Occasionally these relationships become out of sync, most often after an import, update, or migration.', 'buddypress' ); ?> 553 <?php 554 printf( 555 /* translators: %s: the link to the BuddyPress repair tools */ 556 esc_html_x( 'Use the %s to repair these relationships.', 'buddypress tools intro', 'buddypress' ), 557 '<a href="' . esc_url( $url ) . '">' . esc_html__( 'BuddyPress Repair Tools', 'buddypress' ) . '</a>' 558 ); 559 ?> 560 </dd> 561 <dt><?php esc_html_e( 'Manage Opt-outs', 'buddypress' ) ?></dt> 562 <dd> 563 <?php esc_html_e( 'BuddyPress stores opt-out requests from people who are not members of this site, but have been contacted via communication from this site, and wish to opt-out from future communication.', 'buddypress' ); ?> 564 <?php 565 $url = add_query_arg( 'page', 'bp-optouts', bp_get_admin_url( $page ) ); 566 printf( 567 /* translators: %s: the link to the BuddyPress Nonmember Opt-outs */ 568 esc_html_x( 'Visit %s to manage your site’s opt-out requests.', 'buddypress opt-outs intro', 'buddypress' ), 569 '<a href="' . esc_url( $url ) . '">' . esc_html__( 'Nonmember Opt-outs', 'buddypress' ) . '</a>' 570 ); 571 ?> 572 </dd> 573 </dl> 556 574 </div> 557 575 <?php 558 576 } -
src/bp-core/admin/css/common.css
diff --git src/bp-core/admin/css/common.css src/bp-core/admin/css/common.css index c0af4884c..631305fba 100644
TABLE OF CONTENTS: 306 306 content: ""; 307 307 } 308 308 309 body.tools-php .bp-tools dt { 310 font-size: 1.1em; 311 color: #646970; 312 font-weight: 600; 313 margin: 1em 0 0.5em 0; 314 } 315 316 body.tools-php .bp-tools dd { 317 margin: 0; 318 } 319 309 320 /* 310 321 * 2.4 Tooltips 311 322 */ -
src/bp-core/bp-core-cache.php
diff --git src/bp-core/bp-core-cache.php src/bp-core/bp-core-cache.php index 12c674241..35d381a50 100644
function bp_clear_object_type_terms_cache( $type_id = 0, $taxonomy = '' ) { 415 415 add_action( 'bp_type_inserted', 'bp_clear_object_type_terms_cache' ); 416 416 add_action( 'bp_type_updated', 'bp_clear_object_type_terms_cache' ); 417 417 add_action( 'bp_type_deleted', 'bp_clear_object_type_terms_cache' ); 418 419 /** 420 * Resets all incremented bp_optout caches. 421 * 422 * @since 8.0.0 423 */ 424 function bp_optouts_reset_cache_incrementor() { 425 bp_core_reset_incrementor( 'bp_optouts' ); 426 } 427 add_action( 'bp_optout_after_save', 'bp_optouts_reset_cache_incrementor' ); 428 add_action( 'bp_optout_after_delete', 'bp_optouts_reset_cache_incrementor' ); -
src/bp-core/bp-core-functions.php
diff --git src/bp-core/bp-core-functions.php src/bp-core/bp-core-functions.php index 5ae2a54e5..afb941bf8 100644
function bp_get_widget_max_count_limit( $widget_class = '' ) { 4276 4276 */ 4277 4277 return apply_filters( 'bp_get_widget_max_count_limit', 50, $widget_class ); 4278 4278 } 4279 4280 /** 4281 * Add a new BP_Optout. 4282 * 4283 * @since 8.0.0 4284 * 4285 * @param array $args { 4286 * An array of arguments describing the new opt-out. 4287 * @type string $email_address Email address of user who has opted out. 4288 * @type int $user_id Optional. ID of user whose communication 4289 * prompted the user to opt-out. 4290 * @type string $email_type Optional. Name of the email type that 4291 * prompted the user to opt-out. 4292 * @type string $date_modified Optional. Specify a time, else now will be used. 4293 * } 4294 * @return false|int False on failure, ID of new (or existing) opt-out if successful. 4295 */ 4296 function bp_add_optout( $args = array() ) { 4297 $optout = new BP_Optout(); 4298 $r = bp_parse_args( 4299 $args, array( 4300 'email_address' => '', 4301 'user_id' => 0, 4302 'email_type' => '', 4303 'date_modified' => bp_core_current_time(), 4304 ), 4305 'add_optout' 4306 ); 4307 4308 // Opt-outs must have an email address. 4309 if ( empty( $r['email_address'] ) ) { 4310 return false; 4311 } 4312 4313 // Avoid creating duplicate opt-outs. 4314 $optout_id = $optout->optout_exists( 4315 array( 4316 'email_address' => $r['email_address'], 4317 'user_id' => $r['user_id'], 4318 'email_type' => $r['email_type'], 4319 ) 4320 ); 4321 4322 if ( ! $optout_id ) { 4323 // Set up the new opt-out. 4324 $optout->email_address = $r['email_address']; 4325 $optout->user_id = $r['user_id']; 4326 $optout->email_type = $r['email_type']; 4327 $optout->date_modified = $r['date_modified']; 4328 4329 $optout_id = $optout->save(); 4330 } 4331 4332 return $optout_id; 4333 } 4334 4335 /** 4336 * Find matching BP_Optouts. 4337 * 4338 * @since 8.0.0 4339 * 4340 * @see BP_Optout::get() for a description of parameters and return values. 4341 * 4342 * @param array $args See {@link BP_Optout::get()}. 4343 * @return array See {@link BP_Optout::get()}. 4344 */ 4345 function bp_get_optouts( $args = array() ) { 4346 $optout_class = new BP_Optout(); 4347 return $optout_class::get( $args ); 4348 } 4349 4350 /** 4351 * Delete a BP_Optout by ID. 4352 * 4353 * @since 8.0.0 4354 * 4355 * @param int $id ID of the optout to delete. 4356 * @return bool True on success, false on failure. 4357 */ 4358 function bp_delete_optout_by_id( $id = 0 ) { 4359 $optout_class = new BP_Optout(); 4360 return $optout_class::delete_by_id( $id ); 4361 } -
src/bp-core/bp-core-update.php
diff --git src/bp-core/bp-core-update.php src/bp-core/bp-core-update.php index 7cb66c837..1556f6146 100644
function bp_update_to_8_0() { 651 651 } 652 652 } 653 653 } 654 655 bp_core_install_nonmember_opt_outs(); 654 656 } 655 657 656 658 /** -
src/bp-core/classes/class-bp-admin.php
diff --git src/bp-core/classes/class-bp-admin.php src/bp-core/classes/class-bp-admin.php index 617c7d90a..1e10deab7 100644
class BP_Admin { 123 123 require( $this->admin_dir . 'bp-core-admin-components.php' ); 124 124 require( $this->admin_dir . 'bp-core-admin-slugs.php' ); 125 125 require( $this->admin_dir . 'bp-core-admin-tools.php' ); 126 require( $this->admin_dir . 'bp-core-admin-optouts.php' ); 126 127 } 127 128 128 129 /** … … class BP_Admin { 301 302 'bp_core_admin_tools' 302 303 ); 303 304 305 $hooks[] = add_submenu_page( 306 $tools_parent, 307 __( 'Manage Opt-outs', 'buddypress' ), 308 __( 'Manage Opt-outs', 'buddypress' ), 309 $this->capability, 310 'bp-optouts', 311 'bp_core_optouts_admin' 312 ); 313 304 314 // For network-wide configs, add a link to (the root site's) Emails screen. 305 315 if ( is_network_admin() && bp_is_network_activated() ) { 306 316 $email_labels = bp_get_email_post_type_labels(); … … class BP_Admin { 523 533 // About and Credits pages. 524 534 remove_submenu_page( 'index.php', 'bp-about' ); 525 535 remove_submenu_page( 'index.php', 'bp-credits' ); 536 537 // Nonmembers Opt-outs page. 538 if ( is_network_admin() ) { 539 remove_submenu_page( 'network-tools', 'bp-optouts' ); 540 } else { 541 remove_submenu_page( 'tools.php', 'bp-optouts' ); 542 } 526 543 } 527 544 528 545 /** -
new file src/bp-core/classes/class-bp-optout.php
diff --git src/bp-core/classes/class-bp-optout.php src/bp-core/classes/class-bp-optout.php new file mode 100644 index 000000000..90dff5f83
- + 1 <?php 2 /** 3 * BuddyPress Nonmember Opt-out Class 4 * 5 * @package BuddyPress 6 * @subpackage Nonmember Opt-outs 7 * 8 * @since 8.0.0 9 */ 10 11 // Exit if accessed directly. 12 defined( 'ABSPATH' ) || exit; 13 14 /** 15 * BuddyPress opt-outs. 16 * 17 * Use this class to create, access, edit, or delete BuddyPress Nonmember Opt-outs. 18 * 19 * @since 8.0.0 20 */ 21 class BP_Optout { 22 23 /** 24 * The opt-out ID. 25 * 26 * @since 8.0.0 27 * @access public 28 * @var int 29 */ 30 public $id; 31 32 /** 33 * The hashed email address of the user that wishes to opt out of 34 * communications from this site. 35 * 36 * @since 8.0.0 37 * @access public 38 * @var string 39 */ 40 public $email_address; 41 42 /** 43 * The ID of the user that generated the contact that resulted in the opt-out. 44 * 45 * @since 8.0.0 46 * @access public 47 * @var int 48 */ 49 public $user_id; 50 51 /** 52 * The type of email contact that resulted in the opt-out. 53 * This should be one of the known BP_Email types. 54 * 55 * @since 8.0.0 56 * @access public 57 * @var string 58 */ 59 public $email_type; 60 61 /** 62 * The date the opt-out was last modified. 63 * 64 * @since 8.0.0 65 * @access public 66 * @var string 67 */ 68 public $date_modified; 69 70 /** Public Methods ****************************************************/ 71 72 /** 73 * Constructor method. 74 * 75 * @since 8.0.0 76 * 77 * @param int $id Optional. Provide an ID to access an existing 78 * optout item. 79 */ 80 public function __construct( $id = 0 ) { 81 if ( ! empty( $id ) ) { 82 $this->id = (int) $id; 83 $this->populate(); 84 } 85 } 86 87 /** 88 * Get the opt-outs table name. 89 * 90 * @since 8.0.0 91 * @access public 92 * @return string 93 */ 94 public static function get_table_name() { 95 return buddypress()->members->table_name_optouts; 96 } 97 98 /** 99 * Update or insert opt-out details into the database. 100 * 101 * @since 8.0.0 102 * 103 * @global wpdb $wpdb WordPress database object. 104 * 105 * @return bool True on success, false on failure. 106 */ 107 public function save() { 108 109 // Return value 110 $retval = false; 111 112 // Default data and format 113 $data = array( 114 'email_address_hash' => $this->email_address, 115 'user_id' => $this->user_id, 116 'email_type' => sanitize_key( $this->email_type ), 117 'date_modified' => $this->date_modified, 118 ); 119 $data_format = array( '%s', '%d', '%s', '%s' ); 120 121 /** 122 * Fires before an opt-out is saved. 123 * 124 * @since 8.0.0 125 * 126 * @param BP_Optout object $this Characteristics of the opt-out to be saved. 127 */ 128 do_action_ref_array( 'bp_optout_before_save', array( &$this ) ); 129 130 // Update. 131 if ( ! empty( $this->id ) ) { 132 $result = self::_update( $data, array( 'ID' => $this->id ), $data_format, array( '%d' ) ); 133 // Insert. 134 } else { 135 $result = self::_insert( $data, $data_format ); 136 } 137 138 // Set the opt-out ID if successful. 139 if ( ! empty( $result ) && ! is_wp_error( $result ) ) { 140 global $wpdb; 141 142 $this->id = $wpdb->insert_id; 143 $retval = $wpdb->insert_id; 144 } 145 146 wp_cache_delete( $this->id, 'bp_optouts' ); 147 148 /** 149 * Fires after an optout is saved. 150 * 151 * @since 8.0.0 152 * 153 * @param BP_optout object $this Characteristics of the opt-out just saved. 154 */ 155 do_action_ref_array( 'bp_optout_after_save', array( &$this ) ); 156 157 // Return the result. 158 return $retval; 159 } 160 161 /** 162 * Fetch data for an existing opt-out from the database. 163 * 164 * @since 8.0.0 165 * 166 * @global BuddyPress $bp The one true BuddyPress instance. 167 * @global wpdb $wpdb WordPress database object. 168 */ 169 public function populate() { 170 global $wpdb; 171 $optouts_table_name = $this->get_table_name(); 172 173 // Check cache for optout data. 174 $optout = wp_cache_get( $this->id, 'bp_optouts' ); 175 176 // Cache missed, so query the DB. 177 if ( false === $optout ) { 178 $optout = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$optouts_table_name} WHERE id = %d", $this->id ) ); 179 wp_cache_set( $this->id, $optout, 'bp_optouts' ); 180 } 181 182 // No optout found so set the ID and bail. 183 if ( empty( $optout ) || is_wp_error( $optout ) ) { 184 $this->id = 0; 185 return; 186 } 187 188 $this->email_address = $optout->email_address_hash; 189 $this->user_id = (int) $optout->user_id; 190 $this->email_type = sanitize_key( $optout->email_type ); 191 $this->date_modified = $optout->date_modified; 192 193 } 194 195 /** Protected Static Methods ******************************************/ 196 197 /** 198 * Create an opt-out entry. 199 * 200 * @since 8.0.0 201 * 202 * @param array $data { 203 * Array of optout data, passed to {@link wpdb::insert()}. 204 * @type string $email_address The hashed email address of the user that wishes to opt out of 205 * communications from this site. 206 * @type int $user_id The ID of the user that generated the contact that resulted in the opt-out. 207 * @type string $email_type The type of email contact that resulted in the opt-out. 208 * @type string $date_modified Date the opt-out was last modified. 209 * } 210 * @param array $data_format See {@link wpdb::insert()}. 211 * @return int|false The number of rows inserted, or false on error. 212 */ 213 protected static function _insert( $data = array(), $data_format = array() ) { 214 global $wpdb; 215 // We must hash the email address at insert. 216 $data['email_address_hash'] = wp_hash( $data['email_address_hash'] ); 217 return $wpdb->insert( BP_Optout::get_table_name(), $data, $data_format ); 218 } 219 220 /** 221 * Update opt-outs. 222 * 223 * @since 8.0.0 224 * 225 * @see wpdb::update() for further description of paramater formats. 226 * 227 * @param array $data Array of opt-out data to update, passed to 228 * {@link wpdb::update()}. Accepts any property of a 229 * BP_optout object. 230 * @param array $where The WHERE params as passed to wpdb::update(). 231 * Typically consists of array( 'ID' => $id ) to specify the ID 232 * of the item being updated. See {@link wpdb::update()}. 233 * @param array $data_format See {@link wpdb::insert()}. 234 * @param array $where_format See {@link wpdb::insert()}. 235 * @return int|false The number of rows updated, or false on error. 236 */ 237 protected static function _update( $data = array(), $where = array(), $data_format = array(), $where_format = array() ) { 238 global $wpdb; 239 240 // Ensure that a passed email address is hashed. 241 if ( ! empty( $data['email_address_hash'] ) && is_email( $data['email_address_hash'] ) ) { 242 $data['email_address_hash'] = wp_hash( $data['email_address_hash'] ); 243 } 244 245 return $wpdb->update( BP_Optout::get_table_name(), $data, $where, $data_format, $where_format ); 246 } 247 248 /** 249 * Delete opt-outs. 250 * 251 * @since 8.0.0 252 * 253 * @see wpdb::update() for further description of paramater formats. 254 * 255 * @param array $where Array of WHERE clauses to filter by, passed to 256 * {@link wpdb::delete()}. Accepts any property of a 257 * BP_optout object. 258 * @param array $where_format See {@link wpdb::insert()}. 259 * @return int|false The number of rows updated, or false on error. 260 */ 261 protected static function _delete( $where = array(), $where_format = array() ) { 262 global $wpdb; 263 return $wpdb->delete( BP_Optout::get_table_name(), $where, $where_format ); 264 } 265 266 /** 267 * Assemble the WHERE clause of a get() SQL statement. 268 * 269 * Used by BP_optout::get() to create its WHERE 270 * clause. 271 * 272 * @since 8.0.0 273 * 274 * @param array $args See {@link BP_optout::get()} for more details. 275 * @return string WHERE clause. 276 */ 277 protected static function get_where_sql( $args = array() ) { 278 global $wpdb; 279 280 $where_conditions = array(); 281 $where = ''; 282 283 // id. 284 if ( false !== $args['id'] ) { 285 $id_in = implode( ',', wp_parse_id_list( $args['id'] ) ); 286 $where_conditions['id'] = "id IN ({$id_in})"; 287 } 288 289 // email_address. 290 if ( ! empty( $args['email_address'] ) ) { 291 if ( ! is_array( $args['email_address'] ) ) { 292 $emails = explode( ',', $args['email_address'] ); 293 } else { 294 $emails = $args['email_address']; 295 } 296 297 $email_clean = array(); 298 foreach ( $emails as $email ) { 299 $email_hash = wp_hash( $email ); 300 $email_clean[] = $wpdb->prepare( '%s', $email_hash ); 301 } 302 303 $email_in = implode( ',', $email_clean ); 304 $where_conditions['email_address'] = "email_address_hash IN ({$email_in})"; 305 } 306 307 // user_id. 308 if ( ! empty( $args['user_id'] ) ) { 309 $user_id_in = implode( ',', wp_parse_id_list( $args['user_id'] ) ); 310 $where_conditions['user_id'] = "user_id IN ({$user_id_in})"; 311 } 312 313 // email_type. 314 if ( ! empty( $args['email_type'] ) ) { 315 if ( ! is_array( $args['email_type'] ) ) { 316 $email_types = explode( ',', $args['email_type'] ); 317 } else { 318 $email_types = $args['email_type']; 319 } 320 321 $et_clean = array(); 322 foreach ( $email_types as $et ) { 323 $et_clean[] = $wpdb->prepare( '%s', sanitize_key( $et ) ); 324 } 325 326 $et_in = implode( ',', $et_clean ); 327 $where_conditions['email_type'] = "email_type IN ({$et_in})"; 328 } 329 330 // search_terms. 331 if ( ! empty( $args['search_terms'] ) ) { 332 // Matching email_address is an exact match because of the hashing. 333 $search_terms_like = wp_hash( $args['search_terms'] ); 334 $where_conditions['search_terms'] = $wpdb->prepare( '( email_address_hash LIKE %s )', $search_terms_like ); 335 } 336 337 // Custom WHERE. 338 if ( ! empty( $where_conditions ) ) { 339 $where = 'WHERE ' . implode( ' AND ', $where_conditions ); 340 } 341 342 return $where; 343 } 344 345 /** 346 * Assemble the ORDER BY clause of a get() SQL statement. 347 * 348 * Used by BP_Optout::get() to create its ORDER BY 349 * clause. 350 * 351 * @since 8.0.0 352 * 353 * @param array $args See {@link BP_optout::get()} for more details. 354 * @return string ORDER BY clause. 355 */ 356 protected static function get_order_by_sql( $args = array() ) { 357 358 $conditions = array(); 359 $retval = ''; 360 361 // Order by. 362 if ( ! empty( $args['order_by'] ) ) { 363 $order_by_clean = array(); 364 $columns = array( 'id', 'email_address_hash', 'user_id', 'email_type', 'date_modified' ); 365 foreach ( (array) $args['order_by'] as $key => $value ) { 366 if ( in_array( $value, $columns, true ) ) { 367 $order_by_clean[] = $value; 368 } 369 } 370 if ( ! empty( $order_by_clean ) ) { 371 $order_by = implode( ', ', $order_by_clean ); 372 $conditions['order_by'] = "{$order_by}"; 373 } 374 } 375 376 // Sort order direction. 377 if ( ! empty( $args['sort_order'] ) ) { 378 $sort_order = bp_esc_sql_order( $args['sort_order'] ); 379 $conditions['sort_order'] = "{$sort_order}"; 380 } 381 382 // Custom ORDER BY. 383 if ( ! empty( $conditions['order_by'] ) ) { 384 $retval = 'ORDER BY ' . implode( ' ', $conditions ); 385 } 386 387 return $retval; 388 } 389 390 /** 391 * Assemble the LIMIT clause of a get() SQL statement. 392 * 393 * Used by BP_Optout::get() to create its LIMIT clause. 394 * 395 * @since 8.0.0 396 * 397 * @param array $args See {@link BP_optout::get()} for more details. 398 * @return string LIMIT clause. 399 */ 400 protected static function get_paged_sql( $args = array() ) { 401 global $wpdb; 402 403 // Setup local variable. 404 $retval = ''; 405 406 // Custom LIMIT. 407 if ( ! empty( $args['page'] ) && ! empty( $args['per_page'] ) ) { 408 $page = absint( $args['page'] ); 409 $per_page = absint( $args['per_page'] ); 410 $offset = $per_page * ( $page - 1 ); 411 $retval = $wpdb->prepare( "LIMIT %d, %d", $offset, $per_page ); 412 } 413 414 return $retval; 415 } 416 417 /** 418 * Assemble query clauses, based on arguments, to pass to $wpdb methods. 419 * 420 * The insert(), update(), and delete() methods of {@link wpdb} expect 421 * arguments of the following forms: 422 * 423 * - associative arrays whose key/value pairs are column => value, to 424 * be used in WHERE, SET, or VALUES clauses 425 * - arrays of "formats", which tell $wpdb->prepare() which type of 426 * value to expect when sanitizing (eg, array( '%s', '%d' )) 427 * 428 * This utility method can be used to assemble both kinds of params, 429 * out of a single set of associative array arguments, such as: 430 * 431 * $args = array( 432 * 'user_id' => 4, 433 * 'email_type' => 'type_string', 434 * ); 435 * 436 * This will be converted to: 437 * 438 * array( 439 * 'data' => array( 440 * 'user_id' => 4, 441 * 'email_type' => 'type_string', 442 * ), 443 * 'format' => array( 444 * '%d', 445 * '%s', 446 * ), 447 * ) 448 * 449 * which can easily be passed as arguments to the $wpdb methods. 450 * 451 * @since 8.0.0 452 * 453 * @param array $args Associative array of filter arguments. 454 * See {@BP_optout::get()} for a breakdown. 455 * @return array Associative array of 'data' and 'format' args. 456 */ 457 protected static function get_query_clauses( $args = array() ) { 458 $where_clauses = array( 459 'data' => array(), 460 'format' => array(), 461 ); 462 463 // id. 464 if ( ! empty( $args['id'] ) ) { 465 $where_clauses['data']['id'] = absint( $args['id'] ); 466 $where_clauses['format'][] = '%d'; 467 } 468 469 // email_address. 470 if ( ! empty( $args['email_address'] ) ) { 471 $where_clauses['data']['email_address_hash'] = $args['email_address']; 472 $where_clauses['format'][] = '%s'; 473 } 474 475 // user_id. 476 if ( ! empty( $args['user_id'] ) ) { 477 $where_clauses['data']['user_id'] = absint( $args['user_id'] ); 478 $where_clauses['format'][] = '%d'; 479 } 480 481 // email_type. 482 if ( ! empty( $args['email_type'] ) ) { 483 $where_clauses['data']['email_type'] = $args['email_type']; 484 $where_clauses['format'][] = '%s'; 485 } 486 487 return $where_clauses; 488 } 489 490 /** Public Static Methods *********************************************/ 491 492 /** 493 * Get opt-outs, based on provided filter parameters. 494 * 495 * @since 8.0.0 496 * 497 * @param array $args { 498 * Associative array of arguments. All arguments but $page and 499 * $per_page can be treated as filter values for get_where_sql() 500 * and get_query_clauses(). All items are optional. 501 * @type int|array $id ID of opt-out. 502 * Can be an array of IDs. 503 * @type string|array $email_address Email address of users who have opted out 504 * being queried. Can be an array of addresses. 505 * @type int|array $user_id ID of user whose communication prompted the 506 * opt-out. Can be an array of IDs. 507 * @type string|array $email_type Name of the emil type to filter by. 508 * Can be an array of email types. 509 * @type string $search_terms Term to match against email_address field. 510 * @type string $order_by Database column to order by. 511 * @type string $sort_order Either 'ASC' or 'DESC'. 512 * @type int $page Number of the current page of results. 513 * Default: false (no pagination, 514 * all items). 515 * @type int $per_page Number of items to show per page. 516 * Default: false (no pagination, 517 * all items). 518 * @type string $fields Which fields to return. Specify 'email_addresses' to 519 * fetch a list of opt-out email_addresses. 520 * Specify 'user_ids' to 521 * fetch a list of opt-out user_ids. 522 * Specify 'ids' to fetch a list of opt-out IDs. 523 * Default: 'all' (return BP_Optout objects). 524 * } 525 * 526 * @return array BP_Optout objects | IDs of found opt-outs | Email addresses of matches. 527 */ 528 public static function get( $args = array() ) { 529 global $wpdb; 530 $optouts_table_name = BP_Optout::get_table_name(); 531 532 // Parse the arguments. 533 $r = bp_parse_args( 534 $args, 535 array( 536 'id' => false, 537 'email_address' => false, 538 'user_id' => false, 539 'email_type' => false, 540 'search_terms' => '', 541 'order_by' => false, 542 'sort_order' => false, 543 'page' => false, 544 'per_page' => false, 545 'fields' => 'all', 546 ), 547 'bp_optout_get' 548 ); 549 550 $sql = array( 551 'select' => "SELECT", 552 'fields' => '', 553 'from' => "FROM {$optouts_table_name} o", 554 'where' => '', 555 'orderby' => '', 556 'pagination' => '', 557 ); 558 559 if ( 'user_ids' === $r['fields'] ) { 560 $sql['fields'] = "DISTINCT o.user_id"; 561 } else if ( 'email_addresses' === $r['fields'] ) { 562 $sql['fields'] = "DISTINCT o.email_address_hash"; 563 } else { 564 $sql['fields'] = 'DISTINCT o.id'; 565 } 566 567 // WHERE. 568 $sql['where'] = self::get_where_sql( 569 array( 570 'id' => $r['id'], 571 'email_address' => $r['email_address'], 572 'user_id' => $r['user_id'], 573 'email_type' => $r['email_type'], 574 'search_terms' => $r['search_terms'], 575 ) 576 ); 577 578 // ORDER BY. 579 $sql['orderby'] = self::get_order_by_sql( 580 array( 581 'order_by' => $r['order_by'], 582 'sort_order' => $r['sort_order'] 583 ) 584 ); 585 586 // LIMIT %d, %d. 587 $sql['pagination'] = self::get_paged_sql( 588 array( 589 'page' => $r['page'], 590 'per_page' => $r['per_page'], 591 ) 592 ); 593 594 $paged_optouts_sql = "{$sql['select']} {$sql['fields']} {$sql['from']} {$sql['where']} {$sql['orderby']} {$sql['pagination']}"; 595 596 /** 597 * Filters the pagination SQL statement. 598 * 599 * @since 8.0.0 600 * 601 * @param string $value Concatenated SQL statement. 602 * @param array $sql Array of SQL parts before concatenation. 603 * @param array $r Array of parsed arguments for the get method. 604 */ 605 $paged_optouts_sql = apply_filters( 'bp_optouts_get_paged_optouts_sql', $paged_optouts_sql, $sql, $r ); 606 607 $cached = bp_core_get_incremented_cache( $paged_optouts_sql, 'bp_optouts' ); 608 if ( false === $cached ) { 609 $paged_optout_ids = $wpdb->get_col( $paged_optouts_sql ); 610 bp_core_set_incremented_cache( $paged_optouts_sql, 'bp_optouts', $paged_optout_ids ); 611 } else { 612 $paged_optout_ids = $cached; 613 } 614 615 // Special return format cases. 616 if ( in_array( $r['fields'], array( 'ids', 'user_ids' ), true ) ) { 617 // We only want the field that was found. 618 return array_map( 'intval', $paged_optout_ids ); 619 } else if ( 'email_addresses' === $r['fields'] ) { 620 return $paged_optout_ids; 621 } 622 623 $uncached_ids = bp_get_non_cached_ids( $paged_optout_ids, 'bp_optouts' ); 624 if ( $uncached_ids ) { 625 $ids_sql = implode( ',', array_map( 'intval', $uncached_ids ) ); 626 $data_objects = $wpdb->get_results( "SELECT o.* FROM {$optouts_table_name} o WHERE o.id IN ({$ids_sql})" ); 627 foreach ( $data_objects as $data_object ) { 628 wp_cache_set( $data_object->id, $data_object, 'bp_optouts' ); 629 } 630 } 631 632 $paged_optouts = array(); 633 foreach ( $paged_optout_ids as $paged_optout_id ) { 634 $paged_optouts[] = new BP_optout( $paged_optout_id ); 635 } 636 637 return $paged_optouts; 638 } 639 640 /** 641 * Get a count of total optouts matching a set of arguments. 642 * 643 * @since 8.0.0 644 * 645 * @see BP_optout::get() for a description of 646 * arguments. 647 * 648 * @param array $args See {@link BP_optout::get()}. 649 * @return int Count of located items. 650 */ 651 public static function get_total_count( $args ) { 652 global $wpdb; 653 $optouts_table_name = BP_Optout::get_table_name(); 654 655 // Parse the arguments. 656 $r = bp_parse_args( 657 $args, 658 array( 659 'id' => false, 660 'email_address' => false, 661 'user_id' => false, 662 'email_type' => false, 663 'search_terms' => '', 664 'order_by' => false, 665 'sort_order' => false, 666 'page' => false, 667 'per_page' => false, 668 'fields' => 'all', 669 ), 670 'bp_optout_get_total_count' 671 ); 672 673 // Build the query 674 $select_sql = "SELECT COUNT(*)"; 675 $from_sql = "FROM {$optouts_table_name}"; 676 $where_sql = self::get_where_sql( $r ); 677 $sql = "{$select_sql} {$from_sql} {$where_sql}"; 678 679 // Return the queried results 680 return $wpdb->get_var( $sql ); 681 } 682 683 /** 684 * Update optouts. 685 * 686 * @since 8.0.0 687 * 688 * @see BP_optout::get() for a description of 689 * accepted update/where arguments. 690 * 691 * @param array $update_args Associative array of fields to update, 692 * and the values to update them to. Of the format 693 * array( 'user_id' => 4, 'email_address' => 'bar@foo.com', ). 694 * @param array $where_args Associative array of columns/values, to 695 * determine which rows should be updated. Of the format 696 * array( 'user_id' => 7, 'email_address' => 'bar@foo.com', ). 697 * @return int|bool Number of rows updated on success, false on failure. 698 */ 699 public static function update( $update_args = array(), $where_args = array() ) { 700 $update = self::get_query_clauses( $update_args ); 701 $where = self::get_query_clauses( $where_args ); 702 703 /** 704 * Fires before an opt-out is updated. 705 * 706 * @since 8.0.0 707 * 708 * @param array $where_args Associative array of columns/values describing 709 * opt-outs about to be deleted. 710 * @param array $update_args Array of new values. 711 */ 712 do_action( 'bp_optout_before_update', $where_args, $update_args ); 713 714 $retval = self::_update( $update['data'], $where['data'], $update['format'], $where['format'] ); 715 716 // Clear matching items from the cache. 717 $cache_args = $where_args; 718 $cache_args['fields'] = 'ids'; 719 $maybe_cached_ids = self::get( $cache_args ); 720 foreach ( $maybe_cached_ids as $invite_id ) { 721 wp_cache_delete( $invite_id, 'bp_optouts' ); 722 } 723 724 /** 725 * Fires after an opt-out is updated. 726 * 727 * @since 8.0.0 728 * 729 * @param array $where_args Associative array of columns/values describing 730 * opt-outs about to be deleted. 731 * @param array $update_args Array of new values. 732 */ 733 do_action( 'bp_optout_after_update', $where_args, $update_args ); 734 735 return $retval; 736 } 737 738 /** 739 * Delete opt-outs. 740 * 741 * @since 8.0.0 742 * 743 * @see BP_optout::get() for a description of 744 * accepted where arguments. 745 * 746 * @param array $args Associative array of columns/values, to determine 747 * which rows should be deleted. Of the format 748 * array( 'user_id' => 7, 'email_address' => 'bar@foo.com', ). 749 * @return int|bool Number of rows deleted on success, false on failure. 750 */ 751 public static function delete( $args = array() ) { 752 $where = self::get_query_clauses( $args ); 753 754 /** 755 * Fires before an opt-out is deleted. 756 * 757 * @since 8.0.0 758 * 759 * @param array $args Characteristics of the opt-outs to be deleted. 760 */ 761 do_action( 'bp_optout_before_delete', $args ); 762 763 // Clear matching items from the cache. 764 $cache_args = $args; 765 $cache_args['fields'] = 'ids'; 766 $maybe_cached_ids = self::get( $cache_args ); 767 foreach ( $maybe_cached_ids as $invite_id ) { 768 wp_cache_delete( $invite_id, 'bp_optouts' ); 769 } 770 771 $retval = self::_delete( $where['data'], $where['format'] ); 772 773 /** 774 * Fires after an opt-out is deleted. 775 * 776 * @since 8.0.0 777 * 778 * @param array $args Characteristics of the opt-outs just deleted. 779 */ 780 do_action( 'bp_optout_after_delete', $args ); 781 782 return $retval; 783 } 784 785 /** Convenience methods ***********************************************/ 786 787 /** 788 * Check whether an invitation exists matching the passed arguments. 789 * 790 * @since 5.0.0 791 * 792 * @see BP_Optout::get() for a description of accepted parameters. 793 * 794 * @return int|bool ID of first found invitation or false if none found. 795 */ 796 public function optout_exists( $args = array() ) { 797 $exists = false; 798 799 $args['fields'] = 'ids'; 800 $optouts = BP_Optout::get( $args ); 801 if ( $optouts ) { 802 $exists = current( $optouts ); 803 } 804 805 return $exists; 806 } 807 808 /** 809 * Delete a single opt-out by ID. 810 * 811 * @since 8.0.0 812 * 813 * @see BP_optout::delete() for explanation of 814 * return value. 815 * 816 * @param int $id ID of the opt-out item to be deleted. 817 * @return bool True on success, false on failure. 818 */ 819 public static function delete_by_id( $id ) { 820 return self::delete( array( 821 'id' => $id, 822 ) ); 823 } 824 } -
new file src/bp-core/classes/class-bp-optouts-list-table.php
diff --git src/bp-core/classes/class-bp-optouts-list-table.php src/bp-core/classes/class-bp-optouts-list-table.php new file mode 100644 index 000000000..0e9084245
- + 1 <?php 2 /** 3 * BuddyPress Opt-outs List Table class. 4 * 5 * @package BuddyPress 6 * @subpackage CoreAdminClasses 7 * @since 8.0.0 8 */ 9 10 // Exit if accessed directly. 11 defined( 'ABSPATH' ) || exit; 12 13 /** 14 * List table class for nonmember opt-outs admin page. 15 * 16 * @since 8.0.0 17 */ 18 class BP_Optouts_List_Table extends WP_Users_List_Table { 19 20 /** 21 * Opt-out count. 22 * 23 * @since 8.0.0 24 * 25 * @var int 26 */ 27 public $total_items = 0; 28 29 /** 30 * Constructor. 31 * 32 * @since 8.0.0 33 */ 34 public function __construct() { 35 // Define singular and plural labels, as well as whether we support AJAX. 36 parent::__construct( 37 array( 38 'ajax' => false, 39 'plural' => 'optouts', 40 'singular' => 'optout', 41 'screen' => get_current_screen()->id, 42 ) 43 ); 44 } 45 46 /** 47 * Set up items for display in the list table. 48 * 49 * Handles filtering of data, sorting, pagination, and any other data 50 * manipulation required prior to rendering. 51 * 52 * @since 8.0.0 53 */ 54 public function prepare_items() { 55 global $usersearch; 56 57 $search = isset( $_REQUEST['s'] ) ? $_REQUEST['s'] : ''; 58 $per_page = $this->get_items_per_page( str_replace( '-', '_', "{$this->screen->id}_per_page" ) ); 59 $paged = $this->get_pagenum(); 60 61 $args = array( 62 'search_terms' => $search, 63 'order_by' => 'date_modified', 64 'sort_order' => 'DESC', 65 'page' => $paged, 66 'per_page' => $per_page, 67 ); 68 69 if ( isset( $_REQUEST['orderby'] ) ) { 70 $args['order_by'] = $_REQUEST['orderby']; 71 } 72 73 if ( isset( $_REQUEST['order'] ) ) { 74 $args['sort_order'] = $_REQUEST['order']; 75 } 76 77 $this->items = bp_get_optouts( $args ); 78 $optouts_class = new BP_Optout(); 79 $this->total_items = $optouts_class->get_total_count( $args ); 80 81 $this->set_pagination_args( 82 array( 83 'total_items' => $this->total_items, 84 'per_page' => $per_page, 85 ) 86 ); 87 } 88 89 /** 90 * Get the list of views available on this table. 91 * 92 * @since 8.0.0 93 */ 94 public function views() { 95 if ( is_multisite() && bp_core_do_network_admin() ) { 96 $tools_parent = 'admin.php'; 97 } else { 98 $tools_parent = 'tools.php'; 99 } 100 101 $url_base = add_query_arg( 102 array( 103 'page' => 'bp-optouts', 104 ), 105 bp_get_admin_url( $tools_parent ) 106 ); 107 ?> 108 109 <h2 class="screen-reader-text"> 110 <?php 111 /* translators: accessibility text */ 112 esc_html_e( 'Filter opt-outs list', 'buddypress' ); 113 ?> 114 </h2> 115 <ul class="subsubsub"> 116 <?php 117 /** 118 * Fires inside listing of views so plugins can add their own. 119 * 120 * @since 8.0.0 121 * 122 * @param string $url_base Current URL base for view. 123 * @param array $active_filters Current filters being requested. 124 */ 125 do_action( 'bp_optouts_list_table_get_views', $url_base, $this->active_filters ); ?> 126 </ul> 127 <?php 128 } 129 130 /** 131 * Get rid of the extra nav. 132 * 133 * WP_Users_List_Table will add an extra nav to change user's role. 134 * As we're dealing with opt-outs, we don't need this. 135 * 136 * @since 8.0.0 137 * 138 * @param array $which Current table nav item. 139 */ 140 public function extra_tablenav( $which ) { 141 return; 142 } 143 144 /** 145 * Specific opt-out columns. 146 * 147 * @since 8.0.0 148 * 149 * @return array 150 */ 151 public function get_columns() { 152 /** 153 * Filters the nonmember opt-outs columns. 154 * 155 * @since 8.0.0 156 * 157 * @param array $value Array of columns to display. 158 */ 159 return apply_filters( 160 'bp_optouts_list_columns', 161 array( 162 'cb' => '<input type="checkbox" />', 163 'email_address' => __( 'Email Address Hash', 'buddypress' ), 164 'username' => __( 'Email Sender', 'buddypress' ), 165 'user_registered' => __( 'Email Sender Registered', 'buddypress' ), 166 'email_type' => __( 'Email Type', 'buddypress' ), 167 'email_type_description' => __( 'Email Description', 'buddypress' ), 168 'optout_date_modified' => __( 'Date Modified', 'buddypress' ), 169 ) 170 ); 171 } 172 173 /** 174 * Specific bulk actions for opt-outs. 175 * 176 * @since 8.0.0 177 */ 178 public function get_bulk_actions() { 179 if ( current_user_can( 'delete_users' ) ) { 180 $actions['delete'] = _x( 'Delete', 'Optout database record action', 'buddypress' ); 181 } 182 183 return $actions; 184 } 185 186 /** 187 * The text shown when no items are found. 188 * 189 * Nice job, clean sheet! 190 * 191 * @since 8.0.0 192 */ 193 public function no_items() { 194 esc_html_e( 'No opt-outs found.', 'buddypress' ); 195 } 196 197 /** 198 * The columns opt-outs can be reordered by. 199 * 200 * @since 8.0.0 201 */ 202 public function get_sortable_columns() { 203 return array( 204 'username' => 'user_id', 205 'email_type' => 'email_type', 206 'optout_date_modified' => 'date_modified', 207 ); 208 } 209 210 /** 211 * Display opt-out rows. 212 * 213 * @since 8.0.0 214 */ 215 public function display_rows() { 216 $style = ''; 217 foreach ( $this->items as $optout ) { 218 $style = ( ' class="alternate"' == $style ) ? '' : ' class="alternate"'; 219 echo "\n\t" . $this->single_row( $optout, $style ); 220 } 221 } 222 223 /** 224 * Display an opt-out row. 225 * 226 * @since 8.0.0 227 * 228 * @see WP_List_Table::single_row() for explanation of params. 229 * 230 * @param BP_Optout $optout BP_Optout object. 231 * @param string $style Styles for the row. 232 * @param string $role Role to be assigned to user. 233 * @param int $numposts Number of posts. 234 * @return void 235 */ 236 public function single_row( $optout = null, $style = '', $role = '', $numposts = 0 ) { 237 echo '<tr' . $style . ' id="optout-' . intval( $optout->id ) . '">'; 238 echo $this->single_row_columns( $optout ); 239 echo '</tr>'; 240 } 241 242 /** 243 * Markup for the checkbox used to select items for bulk actions. 244 * 245 * @since 8.0.0 246 * 247 * @param BP_Optout $optout BP_Optout object. 248 */ 249 public function column_cb( $optout = null ) { 250 ?> 251 <label class="screen-reader-text" for="optout_<?php echo intval( $optout->id ); ?>"> 252 <?php 253 /* translators: %d: accessibility text. */ 254 printf( esc_html__( 'Select opt-out request: %d', 'buddypress' ), intval( $optout->id ) ); 255 ?> 256 </label> 257 <input type="checkbox" id="optout_<?php echo intval( $optout->id ) ?>" name="optout_ids[]" value="<?php echo esc_attr( $optout->id ) ?>" /> 258 <?php 259 } 260 261 /** 262 * Markup for the checkbox used to select items for bulk actions. 263 * 264 * @since 8.0.0 265 * 266 * @param BP_Optout $optout BP_Optout object. 267 */ 268 public function column_email_address( $optout = null ) { 269 printf( '<a href="mailto:%1$s">%2$s</a>', esc_attr( $optout->email_address ), esc_html( $optout->email_address ) ); 270 271 $actions = array(); 272 273 if ( is_network_admin() ) { 274 $form_url = network_admin_url( 'admin.php' ); 275 } else { 276 $form_url = bp_get_admin_url( 'tools.php' ); 277 } 278 279 // Delete link. 280 $delete_link = add_query_arg( 281 array( 282 'page' => 'bp-optouts', 283 'optout_id' => $optout->id, 284 'action' => 'delete', 285 ), 286 $form_url 287 ); 288 $actions['delete'] = sprintf( '<a href="%1$s" class="delete">%2$s</a>', esc_url( $delete_link ), esc_html__( 'Delete', 'buddypress' ) ); 289 290 /** 291 * Filters the row actions for each opt-out in list. 292 * 293 * @since 8.0.0 294 * 295 * @param array $actions Array of actions and corresponding links. 296 * @param object $optout The BP_Optout. 297 */ 298 $actions = apply_filters( 'bp_optouts_management_row_actions', $actions, $optout ); 299 300 echo $this->row_actions( $actions ); 301 } 302 303 /** 304 * The inviter/site member who sent the email that prompted the opt-out. 305 * 306 * @since 8.0.0 307 * 308 * @param BP_Optout $optout BP_Optout object. 309 */ 310 public function column_username( $optout = null ) { 311 $avatar = get_avatar( $optout->user_id, 32 ); 312 $inviter = get_user_by( 'id', $optout->user_id ); 313 if ( ! $inviter ) { 314 return; 315 } 316 $user_link = bp_core_get_user_domain( $optout->user_id ); 317 echo $avatar . sprintf( '<strong><a href="%1$s" class="edit">%2$s</a></strong><br/>', esc_url( $user_link ), esc_html( $inviter->user_login ) ); 318 } 319 320 /** 321 * Display registration date of user whose communication prompted opt-out. 322 * 323 * @since 8.0.0 324 * 325 * @param BP_Optout $optout BP_Optout object. 326 */ 327 public function column_user_registered( $optout = null ) { 328 $inviter = get_user_by( 'id', $optout->user_id ); 329 if ( ! $inviter ) { 330 return; 331 } 332 echo esc_html( mysql2date( 'Y/m/d g:i:s a', $inviter->user_registered ) ); 333 } 334 335 /** 336 * Display type of email that prompted opt-out. 337 * 338 * @since 8.0.0 339 * 340 * @param BP_Optout $optout BP_Optout object. 341 */ 342 public function column_email_type( $optout = null ) { 343 echo esc_html( $optout->email_type ); 344 } 345 346 /** 347 * Display description of bp-email-type that prompted opt-out. 348 * 349 * @since 8.0.0 350 * 351 * @param BP_Optout $optout BP_Optout object. 352 */ 353 public function column_email_type_description( $optout = null ) { 354 $type_term = get_term_by( 'slug', $optout->email_type, 'bp-email-type' ); 355 if ( $type_term ) { 356 echo esc_html( $type_term->description ); 357 } 358 359 } 360 361 /** 362 * Display opt-out date. 363 * 364 * @since 8.0.0 365 * 366 * @param BP_Optout $optout BP_Optout object. 367 */ 368 public function column_optout_date_modified( $optout = null ) { 369 echo esc_html( mysql2date( 'Y/m/d g:i:s a', $optout->date_modified ) ); 370 } 371 372 /** 373 * Allow plugins to add custom columns. 374 * 375 * @since 8.0.0 376 * 377 * @param BP_Optout $optout BP_Optout object. 378 * @param string $column_name The column name. 379 * @return string 380 */ 381 function column_default( $optout = null, $column_name = '' ) { 382 383 /** 384 * Filters the single site custom columns for plugins. 385 * 386 * @since 8.0.0 387 * 388 * @param string $column_name The column name. 389 * @param BP_Optout $optout BP_Optout object. 390 */ 391 return apply_filters( 'bp_optouts_management_custom_column', '', $column_name, $optout ); 392 } 393 } -
src/bp-members/classes/class-bp-members-admin.php
diff --git src/bp-members/classes/class-bp-members-admin.php src/bp-members/classes/class-bp-members-admin.php index c999cb923..17f73cb37 100644
class BP_Members_Admin { 488 488 'bp-signups', 489 489 array( $this, 'signups_admin' ) 490 490 ); 491 491 492 } 492 493 493 494 $edit_page = 'user-edit'; … … class BP_Members_Admin { 509 510 $this->user_page .= '-network'; 510 511 $this->users_page .= '-network'; 511 512 $this->signups_page .= '-network'; 513 514 $this->members_optouts_page .= '-network'; 512 515 } 513 516 514 517 // Setup the screen ID's. … … class BP_Members_Admin { 2564 2567 2565 2568 return $value; 2566 2569 } 2570 2567 2571 } 2568 2572 endif; // End class_exists check. -
src/bp-members/classes/class-bp-members-component.php
diff --git src/bp-members/classes/class-bp-members-component.php src/bp-members/classes/class-bp-members-component.php index 9e6fbcd42..4db47da8d 100644
class BP_Members_Component extends BP_Component { 178 178 'global_tables' => array( 179 179 'table_name_invitations' => bp_core_get_table_prefix() . 'bp_invitations', 180 180 'table_name_last_activity' => bp_core_get_table_prefix() . 'bp_activity', 181 'table_name_optouts' => bp_core_get_table_prefix() . 'bp_optouts', 181 182 'table_name_signups' => $wpdb->base_prefix . 'signups', // Signups is a global WordPress table. 182 183 ) 183 184 ); -
src/class-buddypress.php
diff --git src/class-buddypress.php src/class-buddypress.php index 3dd1d483c..1af41585b 100644
class BuddyPress { 597 597 'BP_REST_Components_Endpoint' => 'core', 598 598 'BP_REST_Attachments' => 'core', 599 599 'BP_Admin_Types' => 'core', 600 'BP_Optout' => 'core', 601 'BP_Optouts_List_Table' => 'core', 600 602 601 603 'BP_Core_Friends_Widget' => 'friends', 602 604 'BP_REST_Friends_Endpoint' => 'friends', -
new file tests/phpunit/testcases/core/optouts.php
diff --git tests/phpunit/testcases/core/optouts.php tests/phpunit/testcases/core/optouts.php new file mode 100644 index 000000000..7c0d1ecc5
- + 1 <?php 2 /** 3 * @group core 4 * @group optouts 5 */ 6 class BP_Tests_Optouts extends BP_UnitTestCase { 7 public function test_bp_optouts_add_optout_vanilla() { 8 $old_current_user = get_current_user_id(); 9 10 $u1 = $this->factory->user->create(); 11 $this->set_current_user( $u1 ); 12 13 // Create a couple of optouts. 14 $args = array( 15 'email_address' => 'one@wp.org', 16 'user_id' => $u1, 17 'email_type' => 'annoyance' 18 ); 19 $i1 = bp_add_optout( $args ); 20 $args['email_address'] = 'two@wp.org'; 21 $i2 = bp_add_optout( $args ); 22 23 $get_args = array( 24 'user_id' => $u1, 25 'fields' => 'ids', 26 ); 27 $optouts = bp_get_optouts( $get_args ); 28 $this->assertEqualSets( array( $i1, $i2 ), $optouts ); 29 30 $this->set_current_user( $old_current_user ); 31 } 32 33 public function test_bp_optouts_add_optout_avoid_duplicates() { 34 $old_current_user = get_current_user_id(); 35 36 $u1 = $this->factory->user->create(); 37 $this->set_current_user( $u1 ); 38 39 // Create an optouts. 40 $args = array( 41 'email_address' => 'one@wp.org', 42 'user_id' => $u1, 43 'email_type' => 'annoyance' 44 ); 45 $i1 = bp_add_optout( $args ); 46 // Attempt to create a duplicate. Should return existing optout id. 47 $i2 = bp_add_optout( $args ); 48 $this->assertEquals( $i1, $i2 ); 49 50 $this->set_current_user( $old_current_user ); 51 } 52 53 public function test_bp_optouts_delete_optout() { 54 $old_current_user = get_current_user_id(); 55 56 $u1 = $this->factory->user->create(); 57 $this->set_current_user( $u1 ); 58 59 $args = array( 60 'email_address' => 'one@wp.org', 61 'user_id' => $u1, 62 'email_type' => 'annoyance' 63 ); 64 $i1 = bp_add_optout( $args ); 65 bp_delete_optout_by_id( $i1 ); 66 67 $get_args = array( 68 'user_id' => $u1, 69 'fields' => 'ids', 70 ); 71 $optouts = bp_get_optouts( $get_args ); 72 $this->assertTrue( empty( $optouts ) ); 73 74 $this->set_current_user( $old_current_user ); 75 } 76 77 public function test_bp_optouts_get_by_search_terms() { 78 $old_current_user = get_current_user_id(); 79 80 $u1 = $this->factory->user->create(); 81 $this->set_current_user( $u1 ); 82 83 // Create a couple of optouts. 84 $args = array( 85 'email_address' => 'one@wpfrost.org', 86 'user_id' => $u1, 87 'email_type' => 'annoyance' 88 ); 89 $i1 = bp_add_optout( $args ); 90 $args['email_address'] = 'two@wp.org'; 91 $i2 = bp_add_optout( $args ); 92 93 $get_args = array( 94 'search_terms' => 'one@wpfrost.org', 95 'fields' => 'ids', 96 ); 97 $optouts = bp_get_optouts( $get_args ); 98 $this->assertEqualSets( array( $i1 ), $optouts ); 99 100 $this->set_current_user( $old_current_user ); 101 } 102 103 }