Last active
December 8, 2025 20:02
-
-
Save yuriinalivaiko/86bbcffb2e3d64ad9765cf704038b144 to your computer and use it in GitHub Desktop.
This code adds custom filters to the member directory of the Ultimate Member plugin. These filters are grouped - one filter searches in multiple fields.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Add custom grouped filters to the member directory. | |
| * | |
| * Add filters you need to this array. Every filter is an array where: | |
| * - key Filter key. Any valid string key. | |
| * - type Filter type. Accepts: 'text', 'select'. | |
| * - label Filter label (used as the filter placeholder). | |
| * - fields An array of usermeta keys. Filter searches a value in these usermeta. | |
| */ | |
| $um_custom_filters = array( | |
| array( | |
| 'key' => 'my_phone', | |
| 'type' => 'text', | |
| 'label' => 'Phone', | |
| 'fields' => array( | |
| 'mobile_number', | |
| 'phone_number', | |
| ), | |
| ), | |
| array( | |
| 'key' => 'my_hobby', | |
| 'type' => 'select', | |
| 'label' => 'Hobby', | |
| 'fields' => array( | |
| 'um_pet', | |
| 'um_sport', | |
| ), | |
| ), | |
| ); | |
| global $um_custom_filters; | |
| // Add custom filters. | |
| add_filter( 'um_frontend_member_search_filters', function( $search_filters ) { | |
| global $um_custom_filters; | |
| foreach( $um_custom_filters as $f ) { | |
| $search_filters[] = $f['key']; | |
| } | |
| return $search_filters; | |
| } ); | |
| // Add custom filter labels. | |
| add_filter( 'um_members_directory_filter_fields', function( $filter_fields ) { | |
| global $um_custom_filters; | |
| foreach( $um_custom_filters as $f ) { | |
| $filter_fields[ $f['key'] ] = $f['label']; | |
| } | |
| return $filter_fields; | |
| } ); | |
| // Add custom filter types. | |
| add_filter( 'um_members_directory_filter_types', function( $filter_types ) { | |
| global $um_custom_filters; | |
| foreach( $um_custom_filters as $f ) { | |
| $filter_types[ $f['key'] ] = $f['type']; | |
| } | |
| return $filter_types; | |
| } ); | |
| // Add custom filter options. | |
| add_filter( 'um_search_fields', function( $attrs, $field_key ) { | |
| global $um_custom_filters; | |
| foreach( $um_custom_filters as &$f ) { | |
| if ( $field_key === $f['key'] ) { | |
| $attrs = array_merge( $attrs, $f ); | |
| if ( 'select' === $f['type'] ) { | |
| $attrs['type'] = 'select'; | |
| $attrs['metakey'] = current( $f['fields'] ); | |
| // prepare dropdown options. | |
| $f['options'] = array(); | |
| foreach ( $f['fields'] as $field_key ) { | |
| $field_data = UM()->fields()->get_field( $field_key ); | |
| if ( $field_data && ! empty( $field_data['options'] ) ) { | |
| $f['options'] = array_merge( $f['options'], $field_data['options'] ); | |
| } | |
| } | |
| sort( $f['options'] ); | |
| $attrs['options'] = $f['options']; | |
| } | |
| } | |
| } | |
| return $attrs; | |
| }, 10, 2 ); | |
| // Combine options for the filter type "select". | |
| add_filter( 'um_member_directory_filter_select_options_sorted', function( $options, $attrs ) { | |
| global $um_custom_filters; | |
| if ( isset( $attrs['key'] ) ) { | |
| foreach( $um_custom_filters as $f ) { | |
| if ( $attrs['key'] === $f['key'] && ! empty( $f['options'] ) ) { | |
| $options = (array) $f['options']; | |
| } | |
| } | |
| } | |
| return $options; | |
| }, 10, 2 ); | |
| // Modify the um_get_members query (default usermeta table). | |
| add_filter( 'um_prepare_user_query_args', function( $query_args, $directory_data ) { | |
| global $um_custom_filters; | |
| foreach( $um_custom_filters as $f ) { | |
| if ( ! empty( $_POST[ $f['key'] ] ) && ! empty( $f['fields'] ) ) { | |
| $filter_query = array( | |
| 'relation' => 'OR', | |
| ); | |
| switch ( $f['type'] ) { | |
| default: | |
| case 'text': | |
| $value = sanitize_text_field( $_POST[ $f['key'] ] ); | |
| foreach ( $f['fields'] as $field ) { | |
| $filter_query[] = array( | |
| 'key' => $field, | |
| 'value' => $value, | |
| 'compare' => 'LIKE', | |
| ); | |
| } | |
| break; | |
| case 'select': | |
| $values_input = map_deep( $_POST[ $f['key'] ], 'sanitize_text_field' ); | |
| foreach ( $values_input as $value ) { | |
| foreach ( $f['fields'] as $field ) { | |
| $filter_query[] = array( | |
| 'key' => $field, | |
| 'value' => serialize( trim( $value ) ), | |
| 'compare' => 'LIKE', | |
| ); | |
| } | |
| } | |
| break; | |
| } | |
| $query_args['meta_query'][] = $filter_query; | |
| } | |
| } | |
| return $query_args; | |
| }, 99, 2 ); | |
| // Modify the um_get_members query (custom usermeta table). | |
| add_action( 'um_pre_users_query', function( $directory, $directory_data ) { | |
| global $wpdb; | |
| global $um_custom_filters; | |
| foreach( $um_custom_filters as $f ) { | |
| if ( ! empty( $_POST[ $f['key'] ] ) && ! empty( $f['fields'] ) ) { | |
| $table = $wpdb->prefix . 'um_metadata'; | |
| $alias = 'umm' . $f['key']; | |
| $keys = "'" . implode( "','", $f['fields'] ) . "'"; | |
| switch ( $f['type'] ) { | |
| default: | |
| case 'text': | |
| $value = sanitize_text_field( $_POST[ $f['key'] ] ); | |
| $like = '%' . $wpdb->esc_like( $value ) . '%'; | |
| $filter_query = $wpdb->prepare( | |
| "INNER JOIN %i AS %i ON ( %i.user_id = u.ID AND %i.um_key IN ({$keys}) AND %i.um_value LIKE %s )", | |
| $table, | |
| $alias, | |
| $alias, | |
| $alias, | |
| $alias, | |
| $like | |
| ); | |
| break; | |
| case 'select': | |
| $values_input = map_deep( $_POST[ $f['key'] ], 'sanitize_text_field' ); | |
| $values_array = array(); | |
| foreach ( $values_input as $value ) { | |
| $like = '%' . $wpdb->esc_like( serialize( trim( $value ) ) ) . '%'; | |
| $values_array[] = $wpdb->prepare( | |
| "%i.um_value LIKE %s", | |
| $alias, | |
| $like | |
| ); | |
| } | |
| $values = implode( ' OR ', $values_array ); | |
| $filter_query = $wpdb->prepare( | |
| "INNER JOIN %i AS %i ON ( %i.user_id = u.ID AND %i.um_key IN ({$keys}) AND ({$values}) )", | |
| $table, | |
| $alias, | |
| $alias, | |
| $alias, | |
| $alias | |
| ); | |
| break; | |
| } | |
| $directory->joins[] = $filter_query; | |
| } | |
| } | |
| }, 10, 2 ); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This code snippet is a part of the article Use a single control to filter by several fields in the members directory