Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PROD-7348 Update member query and xprofile search query for performance #4431

Merged
merged 25 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5f4f150
PROD-7348 Fix php notice
bb-yudhisthir May 23, 2024
1ff062b
PROD-7348 Update the query for performance
bb-yudhisthir May 28, 2024
c0197da
PROD-7348 member search filter query updates
bb-yudhisthir May 29, 2024
969a585
PROD-7348 member filter related performance updates
bb-yudhisthir Jun 3, 2024
4bd8606
PROD-7348 Logic update for migration and repair tools
bb-yudhisthir Jun 4, 2024
66e5335
PROD-7348 Fix the conflict with group members page
bb-yudhisthir Jun 6, 2024
24fa780
PROD-7348 Update document blocker
bb-yudhisthir Jun 10, 2024
6929715
Merge branch 'release' into PROD-7348
bb-yudhisthir Jun 14, 2024
71522a3
PROD-7348 phpcs and code refactor
bb-yudhisthir Jun 17, 2024
18ea177
PROD-7348 Update logic to check first table exists
bb-yudhisthir Jun 17, 2024
a1bcd2c
PROD-7348 Remove lines under commit
bb-yudhisthir Jun 18, 2024
2438a6d
PROD-7348 - phpcs and phpcbf
jitendrabanjara1991 Jun 19, 2024
d4b3aa0
PROD-7348 Refactor query
bb-yudhisthir Jun 19, 2024
ac021af
PROD-7348 - Refactor query. Like remove diff if condition and join wi…
jitendrabanjara1991 Jun 20, 2024
67c873e
PROD-7348 - Update query as prefix
jitendrabanjara1991 Jun 20, 2024
4c8c395
PROD-7348 - Query formatting
jitendrabanjara1991 Jun 20, 2024
a283f45
PROD-7348 - Update doc comment
jitendrabanjara1991 Jun 20, 2024
ea2033a
PROD-7348 - phpcbf fixes
KartikSuthar Jun 27, 2024
0e3c029
PROD-7348 - phpcbf fixes
KartikSuthar Jun 27, 2024
2f1a5f5
PROD-7348 delete visibility data on fields, field group, user delete
bb-yudhisthir Jun 27, 2024
674c2d3
PROD-7348 Delete xprofile related data when deleting field
bb-yudhisthir Jun 28, 2024
86f06f8
PROD-7348 delete lastactivity on plugin activation and plugin update
bb-yudhisthir Jul 1, 2024
e7a442a
Merge branch 'release' into PROD-7348
KartikSuthar Jul 9, 2024
0b42393
PROD-7348 Remove duplicates last_activity for user
bb-yudhisthir Jul 9, 2024
04c41f4
Merge branch 'release' into PROD-7348
KartikSuthar Jul 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion src/bp-core/admin/bp-core-admin-schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ function bp_core_install_extended_profiles() {

dbDelta( $sql );

bb_core_install_xprofile_visibility();
bp_core_install_default_profiles_fields();
}

Expand Down Expand Up @@ -1231,7 +1232,10 @@ function bp_core_install_suspend() {
PRIMARY KEY (id),
KEY suspend_item_id (item_id,item_type,blog_id),
KEY suspend_item (item_id,item_type),
KEY item_id (item_id)
KEY item_id (item_id),
KEY user_suspended (user_suspended),
KEY hide_parent (hide_parent),
KEY hide_sitewide (hide_sitewide)
) {$charset_collate};";

$sql[] = "CREATE TABLE {$bp_prefix}bp_suspend_details (
Expand Down Expand Up @@ -1375,3 +1379,46 @@ function bb_core_install_subscription() {

dbDelta( $sql );
}

/**
* Install database tables for the xprofile visibility new structure.
*
* @since BuddyBoss [BBVERSION]
*
* @uses bp_core_get_table_prefix()
* @uses dbDelta()
*/
function bb_core_install_xprofile_visibility() {
global $wpdb;

$bp_prefix = bp_core_get_table_prefix();

// Install bb_xprofile_visibility table if already not exists.
$table_exists = $wpdb->get_var( "SHOW TABLES LIKE '{$bp_prefix}bb_xprofile_visibility'" );
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved
if ( ! $table_exists ) {
$sql = array();
$charset_collate = $wpdb->get_charset_collate();

$sql[] = "CREATE TABLE {$bp_prefix}bb_xprofile_visibility (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
field_id bigint(20) unsigned NOT NULL,
user_id bigint(20) unsigned NOT NULL,
value varchar(20) DEFAULT NULL,
last_updated datetime NOT NULL,
PRIMARY KEY (id),
KEY field_id (field_id),
KEY user_id (user_id),
KEY value (value),
UNIQUE KEY unique_field_id_user_id (field_id,user_id)
) {$charset_collate};";

dbDelta( $sql );
}

/**
* Fires after BuddyBoss adds the xprofile visibility table.
*
* @since BuddyBoss [BBVERSION]
*/
do_action( 'bp_core_install_xprofile_visibility' );
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved
}
65 changes: 65 additions & 0 deletions src/bp-core/bp-core-update.php
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,10 @@ function bp_version_updater() {
bb_update_to_2_6_10();
}

if ( $raw_db_version < 21121 ) {
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved
bb_update_to_2_6_20();
}

if ( $raw_db_version !== $current_db ) {
// @todo - Write only data manipulate migration here. ( This is not for DB structure change ).

Expand Down Expand Up @@ -3603,3 +3607,64 @@ function bb_remove_symlinks( $folder_path ) {
closedir( $handle );
}
}

/**
* Add keys for user_suspended, hide_parent, hide_sitewide columns.
*
* @since BuddyBoss [BBVERSION]
*
* @return void
*/
function bb_update_to_2_6_20() {
global $wpdb;

$bp_prefix = function_exists( 'bp_core_get_table_prefix' ) ? bp_core_get_table_prefix() : $wpdb->base_prefix;

// Check if the 'bp_suspend' table exists.
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$table_exists = $wpdb->get_var( "SHOW TABLES LIKE '{$bp_prefix}bp_suspend'" );
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved
if ( $table_exists ) {

// Get all existing indexes for the table.
$indexes = $wpdb->get_col( $wpdb->prepare(
"SELECT index_name
FROM INFORMATION_SCHEMA.STATISTICS
WHERE table_schema = DATABASE()
AND table_name = %s",
"{$bp_prefix}bp_suspend"
));
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved

// Array to store parts of the ALTER TABLE query.
$alter_statements = [];
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved

// Add key for user_suspended if it doesn't exist.
if ( ! in_array( 'user_suspended', $indexes ) ) {
$alter_statements[] = "ADD KEY user_suspended (user_suspended)";
}
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved

// Add key for hide_parent if it doesn't exist.
if ( ! in_array( 'hide_parent', $indexes ) ) {
$alter_statements[] = "ADD KEY hide_parent (hide_parent)";
}
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved

// Add key for hide_sitewide if it doesn't exist.
if ( ! in_array( 'hide_sitewide', $indexes ) ) {
$alter_statements[] = "ADD KEY hide_sitewide (hide_sitewide)";
}
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved

// If there are any statements to execute, run the ALTER TABLE query.
if ( ! empty( $alter_statements ) ) {
$alter_query = "ALTER TABLE {$bp_prefix}bp_suspend " . implode( ', ', $alter_statements );
$wpdb->query( $alter_query ); //phpcs:ignore
}
}

// Run migration.
$is_already_run = get_transient( 'bb_migrate_xprofile_visibility' );
if ( ! $is_already_run ) {
bb_core_install_xprofile_visibility();
bb_migrate_xprofile_visibility( true );
set_transient( 'bb_migrate_xprofile_visibility', 'yes', HOUR_IN_SECONDS );
}

}
18 changes: 8 additions & 10 deletions src/bp-core/classes/class-bp-user-query.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,25 +311,23 @@ public function prepare_user_ids_query() {
case 'active':
case 'newest':
case 'random':
$this->uid_name = 'ID';
$this->uid_table = $wpdb->users;
$sql['select'] = $wpdb->prepare( "SELECT u.{$this->uid_name} as id FROM {$this->uid_table} u LEFT JOIN {$bp->members->table_name_last_activity} a ON u.ID = a.user_id AND a.component = %s AND a.type = 'last_activity' ", buddypress()->members->id );
$sql['where'][] = ' u.user_status = 0 ';
$this->uid_name = 'user_id';
$this->uid_table = $bp->members->table_name_last_activity;
$sql['select'] = "SELECT u.{$this->uid_name} as id FROM {$this->uid_table} u";
$sql['where'][] = $wpdb->prepare( "u.component = %s AND u.type = 'last_activity'", buddypress()->members->id );

if ( 'newest' == $type ) {
$sql['orderby'] = 'ORDER BY u.ID';
$sql['orderby'] = 'ORDER BY u.user_id';
$sql['order'] = 'DESC';
} elseif ( 'random' == $type ) {
$sql['orderby'] = 'ORDER BY rand()';
} else {
$sql['orderby'] = array(
array( 'COALESCE( a.date_recorded, NULL )', 'DESC' ),
array( 'u.display_name', 'ASC' ),
);
$sql['orderby'] = 'ORDER BY u.date_recorded';
$sql['order'] = 'DESC';
}

// Date query.
$date_query = BP_Date_Query::get_where_sql( $date_query, 'a.date_recorded' );
$date_query = BP_Date_Query::get_where_sql( $date_query, 'u.date_recorded' );
if ( ! empty( $date_query ) ) {
$sql['where']['date_query'] = $date_query;
}
Expand Down
19 changes: 0 additions & 19 deletions src/bp-core/profile-search/bps-search.php
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,6 @@ function bp_ps_search( $request, $users = null ) {

$fields = bp_ps_parse_request( $request );

$copied_arr = array();

foreach ( $fields as $f ) {
// Disable search for some individual field.
if ( ! apply_filters( 'bp_ps_field_can_filter', true, $f, $request ) ) {
Expand All @@ -343,23 +341,6 @@ function bp_ps_search( $request, $users = null ) {
$found = call_user_func( $f->search, $f );
$found = apply_filters( 'bp_ps_field_search_results', $found, $f );

$copied_arr = $found;
if ( isset( $copied_arr, $f->id ) && ! empty( $copied_arr ) ) {
foreach ( $copied_arr as $key => $user ) {
$field_visibility = xprofile_get_field_visibility_level( intval( $f->id ), intval( $user ) );
if ( 'adminsonly' === $field_visibility && ! current_user_can( 'administrator' ) ) {
if ( ( $key = array_search( $user, $found ) ) !== false ) {
unset( $found[ $key ] );
}
}
if ( 'friends' === $field_visibility && ! current_user_can( 'administrator' ) && false === friends_check_friendship( intval( $user ), bp_loggedin_user_id() ) ) {
if ( ( $key = array_search( $user, $found ) ) !== false ) {
unset( $found[ $key ] );
}
}
}
}

$match_all = apply_filters( 'bp_ps_match_all', true );
if ( $match_all ) {
$users = isset( $users ) ? array_intersect( $users, $found ) : $found;
Expand Down
116 changes: 63 additions & 53 deletions src/bp-core/profile-search/bps-xprofile.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,43 @@ function bp_ps_xprofile_search( $f ) {
$value = $f->value;
$filter = $f->format . '_' . ( $f->filter == '' ? 'is' : $f->filter );

$sql = array(
$sql = array(
'select' => '',
'where' => array(),
);
$sql['select'] = "SELECT user_id, field_id FROM {$bp->profile->table_name_data}";
$sql['select'] = "SELECT DISTINCT xpd.user_id FROM {$bp->profile->table_name_data} xpd";

if ( 'on' === bp_xprofile_get_meta( $f->group_id, 'group', 'is_repeater_enabled', true ) ) {
$sql['where']['field_id'] = $wpdb->prepare( "field_id IN ( SELECT f.id FROM {$bp->profile->table_name_fields} as f, {$bp->profile->table_name_meta} as m where f.id = m.object_id AND group_id = %d AND f.type = %s AND m.meta_key = '_cloned_from' AND m.meta_value = %d )", $f->group_id, $f->type, $f->id );
} else {
$sql['where']['field_id'] = $wpdb->prepare( 'field_id = %d', $f->id );
}

if (
! current_user_can( 'administrator' )
) {
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved
$field_visibility = array( 'public' );
if ( is_user_logged_in() ) {
$loggin_user_id = bp_loggedin_user_id();
$field_visibility[] = 'loggedin';
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved
if ( bp_is_active( 'friends' ) ) {
$friend_ids_sql = $wpdb->prepare(
"SELECT CASE WHEN initiator_user_id = %d THEN friend_user_id ELSE initiator_user_id END AS friend_id
FROM {$bp->friends->table_name} WHERE is_confirmed = 1 AND( initiator_user_id = %d OR friend_user_id = %d )",
$loggin_user_id,
$loggin_user_id,
$loggin_user_id
);
}
}
$sql['where'][] = "field_id IN (
SELECT field_id FROM {$bp->profile->table_name_visibility} WHERE xpd.user_id = user_id AND ( `value` IN ('" . implode( "','", $field_visibility ) . "')
OR ( `value` = 'friends' AND user_id IN ({$friend_ids_sql}) )
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved
OR ( user_id = {$loggin_user_id} )
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved
)
)";
}

switch ( $filter ) {
case 'integer_range':
if ( isset( $value['min'] ) ) {
Expand Down Expand Up @@ -218,37 +243,7 @@ function bp_ps_xprofile_search( $f ) {
$sql = apply_filters( 'bp_ps_field_sql', $sql, $f );
$query = $sql['select'] . ' WHERE ' . implode( ' AND ', $sql['where'] );

// If repeater enabel then we check repeater field id is private or not.
if ( 'on' === bp_xprofile_get_meta( $f->group_id, 'group', 'is_repeater_enabled', true ) ) {
$results = $wpdb->get_results( $query, ARRAY_A );
$user_ids = array();
if ( ! empty( $results ) ) {
foreach ( $results as $key => $value ) {
$field_id = ! empty( $value['field_id'] ) ? (int) $value['field_id'] : 0;
$user_id = ! empty( $value['user_id'] ) ? (int) $value['user_id'] : 0;
if ( ! empty( $field_id ) && ! empty( $user_id ) ) {
$field_visibility = xprofile_get_field_visibility_level( intval( $field_id ), intval( $user_id ) );
if (
! current_user_can( 'administrator' ) &&
(
'adminsonly' === $field_visibility ||
(
bp_is_active( 'friends' ) &&
'friends' === $field_visibility &&
false === friends_check_friendship( intval( $user_id ), bp_loggedin_user_id() )
)
)
) {
unset( $results[ $key ] );
} else {
$user_ids[] = $user_id;
}
}
}
}
} else {
$user_ids = $wpdb->get_col( $query );
}
$user_ids = $wpdb->get_col( $query );

return $user_ids;
}
Expand Down Expand Up @@ -621,22 +616,49 @@ function bp_ps_anyfield_search( $f ) {
'select' => '',
'where' => array(),
);
$sql['select'] = "SELECT DISTINCT user_id, field_id FROM {$bp->profile->table_name_data}";

$sql['select'] = "SELECT DISTINCT xpd.user_id as user_id, xpd.field_id as field_id FROM {$bp->profile->table_name_data} xpd";

if (
! current_user_can( 'administrator' )
) {
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved
$field_visibility = array( 'public' );
if ( is_user_logged_in() ) {
$loggin_user_id = bp_loggedin_user_id();
$field_visibility[] = 'loggedin';
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved
if ( bp_is_active( 'friends' ) ) {
$friend_ids_sql = $wpdb->prepare(
"SELECT CASE WHEN initiator_user_id = %d THEN friend_user_id ELSE initiator_user_id END AS friend_id
FROM {$bp->friends->table_name} WHERE is_confirmed = 1 AND( initiator_user_id = %d OR friend_user_id = %d )",
$loggin_user_id,
$loggin_user_id,
$loggin_user_id
);
}
}

$sql['where'][] = "xpd.field_id IN (
SELECT xpv.field_id FROM {$bp->profile->table_name_visibility} xpv WHERE xpv.user_id = xpd.user_id AND ( xpv.value IN ('" . implode( "','", $field_visibility ) . "')
OR ( xpv.value = 'friends' AND xpv.user_id IN ({$friend_ids_sql}) )
OR ( xpv.user_id = {$loggin_user_id} )
bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved
)
)";
}

switch ( $filter ) {
case 'contains':
$escaped = '%' . bp_ps_esc_like( $value ) . '%';
$sql['where'][ $filter ] = $wpdb->prepare( 'value LIKE %s', $escaped );
$sql['where'][ $filter ] = $wpdb->prepare( 'xpd.value LIKE %s', $escaped );
break;

case '':
$sql['where'][ $filter ] = $wpdb->prepare( 'value = %s', $value );
$sql['where'][ $filter ] = $wpdb->prepare( 'xpd.value = %s', $value );
break;

case 'like':
$value = str_replace( '\\\\%', '\\%', $value );
$value = str_replace( '\\\\_', '\\_', $value );
$sql['where'][ $filter ] = $wpdb->prepare( 'value LIKE %s', $value );
$sql['where'][ $filter ] = $wpdb->prepare( 'xpd.value LIKE %s', $value );
break;
}

Expand All @@ -655,6 +677,7 @@ function bp_ps_anyfield_search( $f ) {
'user_id' => false,
)
);

bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved
$fields_array = array();
if ( ! empty( $group_ids ) ) {
foreach ( $group_ids as $group_value ) {
Expand All @@ -666,6 +689,7 @@ function bp_ps_anyfield_search( $f ) {
}
}
}

bb-yudhisthir marked this conversation as resolved.
Show resolved Hide resolved
foreach ( $results as $key => $value ) {
$field_id = ! empty( $value['field_id'] ) ? (int) $value['field_id'] : 0;
$user_id = ! empty( $value['user_id'] ) ? (int) $value['user_id'] : 0;
Expand All @@ -674,22 +698,8 @@ function bp_ps_anyfield_search( $f ) {
unset( $results[ $key ] );
continue;
}
$field_visibility = xprofile_get_field_visibility_level( intval( $field_id ), intval( $user_id ) );
if (
! current_user_can( 'administrator' ) &&
(
'adminsonly' === $field_visibility ||
(
bp_is_active( 'friends' ) &&
'friends' === $field_visibility &&
false === friends_check_friendship( intval( $user_id ), bp_loggedin_user_id() )
)
)
) {
unset( $results[ $key ] );
} else {
$user_ids[] = $user_id;
}

$user_ids[] = $user_id;
}
}
}
Expand Down
Loading