Merge branch 'development/2.8.x' into feature/search_exclude_fields

This commit is contained in:
Mykyta Synelnikov
2024-04-09 01:09:13 +03:00
committed by GitHub
101 changed files with 11230 additions and 8921 deletions
+203 -89
View File
@@ -58,7 +58,11 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
var $filter_types = array();
/**
* Fields used for searching from wp_users table.
*
* @var string[]
*/
var $core_search_fields = array(
'user_login',
'user_url',
@@ -67,6 +71,19 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
'user_nicename',
);
/**
* Fields used for sorting from wp_users table.
*
* @var string[]
*/
var $core_users_fields = array(
'user_login',
'user_url',
'display_name',
'user_email',
'user_nicename',
'user_registered',
);
/**
* @var
@@ -408,7 +425,7 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
'first_name' => __( 'First Name', 'ultimate-member' ),
'last_name' => __( 'Last Name', 'ultimate-member' ),
'nickname' => __( 'Nickname', 'ultimate-member' ),
'secondary_user_email' => __( 'Secondary E-mail Address', 'ultimate-member' ),
'secondary_user_email' => __( 'Secondary Email Address', 'ultimate-member' ),
'description' => __( 'Biography', 'ultimate-member' ),
'phone_number' => __( 'Phone Number', 'ultimate-member' ),
'mobile_number' => __( 'Mobile Number', 'ultimate-member' ),
@@ -1314,24 +1331,24 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$this->query_args['paged'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
}
/**
* Add sorting attributes for \WP_Users_Query
*
* @param array $directory_data Member Directory options
*/
function sorting_query( $directory_data ) {
public function sorting_query( $directory_data ) {
// sort members by
$this->query_args['order'] = 'ASC';
$sortby = ! empty( $_POST['sorting'] ) ? sanitize_text_field( $_POST['sorting'] ) : $directory_data['sortby'];
$sortby = ( $sortby == 'other' ) ? $directory_data['sortby_custom'] : $sortby;
$sortby = ( 'other' === $sortby ) ? $directory_data['sortby_custom'] : $sortby;
$custom_sort = array();
if ( ! empty( $directory_data['sorting_fields'] ) ) {
$sorting_fields = maybe_unserialize( $directory_data['sorting_fields'] );
foreach ( $sorting_fields as $field ) {
if ( is_array( $field ) ) {
$field_keys = array_keys( $field );
$field_keys = array_keys( $field );
$custom_sort[] = $field_keys[0];
}
}
@@ -1384,7 +1401,7 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$this->query_args['order'] = 'ASC';
}
} elseif ( in_array( $sortby, array( 'last_name', 'first_name', 'nickname' ) ) ) {
} elseif ( in_array( $sortby, array( 'last_name', 'first_name', 'nickname' ), true ) ) {
$this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( $sortby . '_c' => array(
'key' => $sortby,
@@ -1426,7 +1443,7 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$this->query_args['orderby'] = array( 'last_name_c' => 'ASC', 'first_name_c' => 'ASC' );
unset( $this->query_args['order'] );
} elseif ( count( $numeric_sorting_keys ) && in_array( $sortby, $numeric_sorting_keys ) ) {
} elseif ( count( $numeric_sorting_keys ) && in_array( $sortby, $numeric_sorting_keys, true ) ) {
$order = 'DESC';
if ( strstr( $sortby, '_desc' ) ) {
@@ -1458,18 +1475,23 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
)
);
$this->query_args['orderby'] = array( $sortby . '_ns' => $order, 'user_registered' => 'DESC' );
$this->query_args['orderby'] = array(
$sortby . '_ns' => $order,
'user_registered' => 'DESC',
);
unset( $this->query_args['order'] );
} elseif ( ( ! empty( $directory_data['sortby_custom'] ) && $sortby == $directory_data['sortby_custom'] ) || in_array( $sortby, $custom_sort ) ) {
} elseif ( ( ! empty( $directory_data['sortby_custom'] ) && $sortby === $directory_data['sortby_custom'] ) || in_array( $sortby, $custom_sort, true ) ) {
$custom_sort_order = ! empty( $directory_data['sortby_custom_order'] ) ? $directory_data['sortby_custom_order'] : 'ASC';
$meta_query = new \WP_Meta_Query();
$custom_sort_type = ! empty( $directory_data['sortby_custom_type'] ) ? $meta_query->get_cast_for_type( $directory_data['sortby_custom_type'] ) : 'CHAR';
if ( ! empty( $directory_data['sorting_fields'] ) ) {
// phpcs:ignore WordPress.Security.NonceVerification -- already verified here
$sorting = sanitize_text_field( $_POST['sorting'] );
$sorting_fields = maybe_serialize( $directory_data['sorting_fields'] );
$sorting_fields = maybe_unserialize( $directory_data['sorting_fields'] );
if ( ! empty( $sorting_fields ) && is_array( $sorting_fields ) ) {
foreach ( $sorting_fields as $field ) {
if ( isset( $field[ $sorting ] ) ) {
@@ -1777,6 +1799,7 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
* Handle filters request
*/
function filters( $directory_data ) {
global $wpdb;
//filters
$filter_query = array();
if ( ! empty( $directory_data['search_fields'] ) ) {
@@ -1809,9 +1832,11 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
continue;
}
/** This filter is documented in includes/core/class-member-directory-meta.php */
$relation = apply_filters( 'um_members_directory_select_filter_relation', 'OR', $field );
switch ( $field ) {
default:
$filter_type = $this->filter_types[ $field ];
/**
@@ -1865,35 +1890,35 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
case 'select':
if ( is_array( $value ) ) {
$field_query = array( 'relation' => 'OR' );
$field_query = array( 'relation' => esc_sql( $relation ) );
foreach ( $value as $single_val ) {
$single_val = trim( stripslashes( $single_val ) );
$arr_meta_query = array(
array(
'key' => $field,
'value' => $single_val,
'compare' => '=',
'key' => $field,
'value' => $single_val,
'compare' => '=',
),
array(
'key' => $field,
'value' => serialize( (string) $single_val ),
'compare' => 'LIKE',
'key' => $field,
'value' => serialize( (string) $single_val ),
'compare' => 'LIKE',
),
array(
'key' => $field,
'value' => '"' . $single_val . '"',
'compare' => 'LIKE',
)
'key' => $field,
'value' => '"' . $single_val . '"',
'compare' => 'LIKE',
),
);
if ( is_numeric( $single_val ) ) {
$arr_meta_query[] = array(
'key' => $field,
'value' => serialize( (int) $single_val ),
'compare' => 'LIKE',
'key' => $field,
'value' => serialize( absint( $single_val ) ),
'compare' => 'LIKE',
);
}
@@ -1967,26 +1992,39 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
if ( ! empty( $field_query ) && $field_query !== true ) {
$this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( $field_query ) );
}
break;
case 'role':
$value = array_map( 'strtolower', $value );
if ( ! empty( $this->query_args['role__in'] ) ) {
$this->query_args['role__in'] = is_array( $this->query_args['role__in'] ) ? $this->query_args['role__in'] : array( $this->query_args['role__in'] );
$default_role = array_intersect( $this->query_args['role__in'], $value );
$um_role = array_diff( $value, $default_role );
foreach ( $um_role as $key => &$val ) {
$val = 'um_' . str_replace( ' ', '-', $val );
if ( 'OR' !== $relation ) {
$role__in_clauses = array( 'relation' => $relation );
foreach ( $value as $role ) {
$role__in_clauses[] = array(
'key' => $wpdb->get_blog_prefix() . 'capabilities',
'value' => '"' . $role . '"',
'compare' => 'LIKE',
);
}
$this->query_args['role__in'] = array_merge( $default_role, $um_role );
$this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( $role__in_clauses ) );
$this->custom_filters_in_query[ $field ] = $value;
} else {
$this->query_args['role__in'] = $value;
};
if ( ! empty( $this->query_args['role__in'] ) ) {
$this->query_args['role__in'] = is_array( $this->query_args['role__in'] ) ? $this->query_args['role__in'] : array( $this->query_args['role__in'] );
$default_role = array_intersect( $this->query_args['role__in'], $value );
$um_role = array_diff( $value, $default_role );
$this->custom_filters_in_query[ $field ] = $this->query_args['role__in'];
foreach ( $um_role as $key => &$val ) {
$val = 'um_' . str_replace( ' ', '-', $val );
}
$this->query_args['role__in'] = array_merge( $default_role, $um_role );
} else {
$this->query_args['role__in'] = $value;
}
$this->custom_filters_in_query[ $field ] = $this->query_args['role__in'];
}
break;
case 'birth_date':
$from_date = date( 'Y/m/d', mktime( 0,0,0, date( 'm', time() ), date( 'd', time() ), date( 'Y', time() - min( $value ) * YEAR_IN_SECONDS ) ) );
@@ -2008,7 +2046,6 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
break;
case 'user_registered':
$offset = 0;
if ( isset( $_POST['gmt_offset'] ) && is_numeric( $_POST['gmt_offset'] ) ) {
$offset = (int) $_POST['gmt_offset'];
@@ -2044,6 +2081,7 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$from_date = (int) min( $value ) + ( $offset * HOUR_IN_SECONDS ); // client time zone offset
$to_date = (int) max( $value ) + ( $offset * HOUR_IN_SECONDS ) + DAY_IN_SECONDS - 1; // time 23:59
$meta_query = array(
'relation' => 'AND',
array(
'key' => '_um_last_login',
'value' => array( gmdate( 'Y-m-d H:i:s', $from_date ), gmdate( 'Y-m-d H:i:s', $to_date ) ),
@@ -2051,12 +2089,54 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
'inclusive' => true,
'type' => 'DATETIME',
),
array(
'relation' => 'OR',
array(
'key' => 'um_show_last_login',
'compare' => 'NOT EXISTS',
),
array(
'key' => 'um_show_last_login',
'value' => 'a:1:{i:0;s:2:"no";}',
'compare' => '!=',
),
),
);
$this->custom_filters_in_query[ $field ] = $value;
$this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( $meta_query ) );
break;
case 'gender':
if ( is_array( $value ) ) {
$field_query = array( 'relation' => $relation );
foreach ( $value as $single_val ) {
$single_val = trim( stripslashes( $single_val ) );
$arr_meta_query = array(
array(
'key' => $field,
'value' => $single_val,
'compare' => '=',
),
array(
'key' => $field,
'value' => '"' . $single_val . '"',
'compare' => 'LIKE',
),
);
$field_query = array_merge( $field_query, $arr_meta_query );
}
}
if ( ! empty( $field_query ) ) {
$this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( $field_query ) );
$this->custom_filters_in_query[ $field ] = $value;
}
break;
}
}
}
@@ -2133,35 +2213,36 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$value = array( $value );
}
$field_query = array( 'relation' => 'OR' );
/** This filter is documented in includes/core/class-member-directory.php */
$field_query = apply_filters( 'um_members_directory_filter_select', array( 'relation' => 'OR' ), $field );
foreach ( $value as $single_val ) {
$single_val = trim( $single_val );
$arr_meta_query = array(
array(
'key' => $field,
'value' => $single_val,
'compare' => '=',
'key' => $field,
'value' => $single_val,
'compare' => '=',
),
array(
'key' => $field,
'value' => serialize( (string) $single_val ),
'compare' => 'LIKE',
'key' => $field,
'value' => serialize( (string) $single_val ),
'compare' => 'LIKE',
),
array(
'key' => $field,
'value' => '"' . $single_val . '"',
'compare' => 'LIKE',
)
'key' => $field,
'value' => '"' . $single_val . '"',
'compare' => 'LIKE',
),
);
if ( is_numeric( $single_val ) ) {
$arr_meta_query[] = array(
'key' => $field,
'value' => serialize( (int) $single_val ),
'compare' => 'LIKE',
'key' => $field,
'value' => serialize( absint( $single_val ) ),
'compare' => 'LIKE',
);
}
@@ -2290,9 +2371,18 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$offset = $gmt_offset;
}
$from_date = (int) min( $value ) + ( $offset * HOUR_IN_SECONDS ); // client time zone offset
$to_date = (int) max( $value ) + ( $offset * HOUR_IN_SECONDS ) + DAY_IN_SECONDS - 1; // time 23:59
$value = array_map(
function( $date ) {
return is_numeric( $date ) ? $date : strtotime( $date );
},
$value
);
$from_date = gmdate( 'Y-m-d H:i:s', (int) min( $value ) + ( $offset * HOUR_IN_SECONDS ) ); // client time zone offset
$to_date = gmdate( 'Y-m-d H:i:s', (int) max( $value ) + ( $offset * HOUR_IN_SECONDS ) + DAY_IN_SECONDS - 1 ); // time 23:59
$meta_query = array(
'relation' => 'AND',
array(
'key' => '_um_last_login',
'value' => array( $from_date, $to_date ),
@@ -2300,6 +2390,18 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
'inclusive' => true,
'type' => 'DATETIME',
),
array(
'relation' => 'OR',
array(
'key' => 'um_show_last_login',
'compare' => 'NOT EXISTS',
),
array(
'key' => 'um_show_last_login',
'value' => 'a:1:{i:0;s:2:"no";}',
'compare' => '!=',
),
),
);
$this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( $meta_query ) );
@@ -2385,8 +2487,8 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
if ( UM()->roles()->um_current_user_can( 'edit', $user_id ) ) {
$actions['um-editprofile'] = array(
'title' => __( 'Edit Profile', 'ultimate-member' ),
'url' => um_edit_profile_url(),
'title' => esc_html__( 'Edit Profile', 'ultimate-member' ),
'url' => um_edit_profile_url(),
);
}
@@ -2417,8 +2519,8 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$url = add_query_arg( array( 'um_action' => $id, 'uid' => $user_id ), um_get_core_page( 'user' ) );
$actions[ $id ] = array(
'title' => $arr['label'],
'url' => $url,
'title' => esc_html( $arr['label'] ),
'url' => esc_url( $url ),
);
}
}
@@ -2429,25 +2531,24 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
if ( empty( UM()->user()->cannot_edit ) ) {
$actions['um-editprofile'] = array(
'title' => __( 'Edit Profile', 'ultimate-member' ),
'title' => esc_html__( 'Edit Profile', 'ultimate-member' ),
'url' => um_edit_profile_url(),
);
}
$actions['um-myaccount'] = array(
'title' => __( 'My Account', 'ultimate-member' ),
'title' => esc_html__( 'My Account', 'ultimate-member' ),
'url' => um_get_core_page( 'account' ),
);
$actions['um-logout'] = array(
'title' => __( 'Logout', 'ultimate-member' ),
'title' => esc_html__( 'Logout', 'ultimate-member' ),
'url' => um_get_core_page( 'logout' ),
);
$actions = apply_filters( 'um_member_directory_my_user_card_actions', $actions, $user_id );
}
return $actions;
}
@@ -2464,7 +2565,7 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$dropdown_actions = $this->build_user_actions_list( $user_id );
$actions = array();
$actions = array();
$can_edit = UM()->roles()->um_current_user_can( 'edit', $user_id );
// Replace hook 'um_members_just_after_name'
@@ -2478,21 +2579,21 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$hook_after_user_name = ob_get_clean();
$data_array = array(
'card_anchor' => substr( md5( $user_id ), 10, 5 ),
'id' => $user_id,
'role' => um_user( 'role' ),
'account_status' => um_user( 'account_status' ),
'account_status_name' => um_user( 'account_status_name' ),
'cover_photo' => um_user( 'cover_photo', $this->cover_size ),
'display_name' => um_user( 'display_name' ),
'profile_url' => um_user_profile_url(),
'can_edit' => $can_edit,
'edit_profile_url' => um_edit_profile_url(),
'avatar' => get_avatar( $user_id, $this->avatar_size ),
'display_name_html' => um_user( 'display_name', 'html' ),
'dropdown_actions' => $dropdown_actions,
'hook_just_after_name' => preg_replace( '/^\s+/im', '', $hook_just_after_name ),
'hook_after_user_name' => preg_replace( '/^\s+/im', '', $hook_after_user_name ),
'card_anchor' => esc_html( substr( md5( $user_id ), 10, 5 ) ),
'id' => absint( $user_id ),
'role' => esc_html( um_user( 'role' ) ),
'account_status' => esc_html( um_user( 'account_status' ) ),
'account_status_name' => esc_html( um_user( 'account_status_name' ) ),
'cover_photo' => wp_kses( um_user( 'cover_photo', $this->cover_size ), UM()->get_allowed_html( 'templates' ) ),
'display_name' => esc_html( um_user( 'display_name' ) ),
'profile_url' => esc_url( um_user_profile_url() ),
'can_edit' => (bool) $can_edit,
'edit_profile_url' => esc_url( um_edit_profile_url() ),
'avatar' => wp_kses( get_avatar( $user_id, $this->avatar_size ), UM()->get_allowed_html( 'templates' ) ),
'display_name_html' => wp_kses( um_user( 'display_name', 'html' ), UM()->get_allowed_html( 'templates' ) ),
'dropdown_actions' => $dropdown_actions,
'hook_just_after_name' => wp_kses( preg_replace( '/^\s+/im', '', $hook_just_after_name ), UM()->get_allowed_html( 'templates' ) ),
'hook_after_user_name' => wp_kses( preg_replace( '/^\s+/im', '', $hook_after_user_name ), UM()->get_allowed_html( 'templates' ) ),
);
if ( ! empty( $directory_data['show_tagline'] ) ) {
@@ -2506,13 +2607,20 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
continue;
}
if ( '_um_last_login' === $key ) {
$show_last_login = get_user_meta( $user_id, 'um_show_last_login', true );
if ( ! empty( $show_last_login ) && 'no' === $show_last_login[0] ) {
continue;
}
}
$value = um_filtered_value( $key );
if ( ! $value ) {
continue;
}
$data_array[ $key ] = $value;
$data_array[ $key ] = wp_kses( $value, UM()->get_allowed_html( 'templates' ) );
}
}
}
@@ -2530,6 +2638,13 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
continue;
}
if ( '_um_last_login' === $key ) {
$show_last_login = get_user_meta( $user_id, 'um_show_last_login', true );
if ( ! empty( $show_last_login ) && 'no' === $show_last_login[0] ) {
continue;
}
}
$value = um_filtered_value( $key );
if ( ! $value ) {
continue;
@@ -2543,8 +2658,8 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
) );
}
$data_array[ "label_{$key}" ] = __( $label, 'ultimate-member' );
$data_array[ $key ] = $value;
$data_array[ "label_{$key}" ] = esc_html__( $label, 'ultimate-member' );
$data_array[ $key ] = wp_kses( $value, UM()->get_allowed_html( 'templates' ) );
}
}
}
@@ -2554,7 +2669,7 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
UM()->fields()->show_social_urls();
$social_urls = ob_get_clean();
$data_array['social_urls'] = $social_urls;
$data_array['social_urls'] = wp_kses( $social_urls, UM()->get_allowed_html( 'templates' ) );
}
}
@@ -2643,14 +2758,13 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
// Prepare default user query values
$this->query_args = array(
'fields' => 'ids',
'number' => 0,
'meta_query' => array(
'relation' => 'AND'
'fields' => 'ids',
'number' => 0,
'meta_query' => array(
'relation' => 'AND',
),
);
// handle different restrictions
$this->restriction_options();
@@ -2784,7 +2898,7 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) {
$this->cover_size = apply_filters( 'um_member_directory_cover_image_size', $this->cover_size, $directory_data );
$avatar_size = UM()->options()->get( 'profile_photosize' );
$avatar_size = UM()->options()->get( 'profile_photosize' );
$this->avatar_size = str_replace( 'px', '', $avatar_size );
$this->avatar_size = apply_filters( 'um_member_directory_avatar_image_size', $this->avatar_size, $directory_data );