diff --git a/includes/admin/assets/js/um-admin-forms.js b/includes/admin/assets/js/um-admin-forms.js index 74d47bcc..c317cbd8 100644 --- a/includes/admin/assets/js/um-admin-forms.js +++ b/includes/admin/assets/js/um-admin-forms.js @@ -245,21 +245,18 @@ jQuery(document).ready( function() { html += ''; } + let dataTypesOptions = ''; + jQuery.each( um_forms_data.md_sorting_data_types, function( key, label ) { + dataTypesOptions += '' + label + ''; + } ); + html += '' + selector_html + '' + '' + '' + wp.i18n.__( 'Remove', 'ultimate-member' ) + '' + '' + '' + wp.i18n.__( 'Meta key', 'ultimate-member' ) + ': ' + '' + wp.i18n.__( 'Data type', 'ultimate-member' ) + ': ' + - '' + wp.i18n.__( 'CHAR', 'ultimate-member' ) + '' + - '' + wp.i18n.__( 'NUMERIC', 'ultimate-member' ) + '' + - '' + wp.i18n.__( 'BINARY', 'ultimate-member' ) + '' + - '' + wp.i18n.__( 'DATE', 'ultimate-member' ) + '' + - '' + wp.i18n.__( 'DATETIME', 'ultimate-member' ) + '' + - '' + wp.i18n.__( 'DECIMAL', 'ultimate-member' ) + '' + - '' + wp.i18n.__( 'SIGNED', 'ultimate-member' ) + '' + - '' + wp.i18n.__( 'TIME', 'ultimate-member' ) + '' + - '' + wp.i18n.__( 'UNSIGNED', 'ultimate-member' ) + '' + + dataTypesOptions + '' + '' + wp.i18n.__( 'Order', 'ultimate-member' ) + ': ' + '' + wp.i18n.__( 'ASC', 'ultimate-member' ) + '' + diff --git a/includes/admin/class-admin.php b/includes/admin/class-admin.php index 2e8b66ef..25974780 100644 --- a/includes/admin/class-admin.php +++ b/includes/admin/class-admin.php @@ -1,21 +1,18 @@ UM()->member_directory()->sort_data_types, ) ); diff --git a/includes/admin/core/class-admin-forms.php b/includes/admin/core/class-admin-forms.php index 68995432..1d5e12fa 100644 --- a/includes/admin/core/class-admin-forms.php +++ b/includes/admin/core/class-admin-forms.php @@ -1613,7 +1613,7 @@ if ( ! class_exists( 'um\admin\core\Admin_Forms' ) ) { $other_order = $value['order']; } } else { - if ( ! in_array( $value, array_keys( $field_data['options'] ) ) ) { + if ( ! array_key_exists( $value, $field_data['options'] ) ) { continue; } } @@ -1623,7 +1623,7 @@ if ( ! class_exists( 'um\admin\core\Admin_Forms' ) ) { $options = ''; foreach ( $field_data['options'] as $key => $option ) { if ( is_array( $value ) ) { - $selected = selected( $key == 'other', true, false ); + $selected = selected( 'other' === $key, true, false ); } else { $selected = selected( $key == $value, true, false ); } @@ -1635,21 +1635,19 @@ if ( ! class_exists( 'um\admin\core\Admin_Forms' ) ) { if ( $sorting ) { $html .= ''; } + + $data_types_html = ''; + foreach ( UM()->member_directory()->sort_data_types as $type_key => $type_label ) { + $data_types_html .= '' . esc_html( $type_label ) . ''; + } + $html .= ' ' . $options . ' ' . __( 'Remove', 'ultimate-member' ) . ' ' . __( 'Meta key', 'ultimate-member' ) . ': - ' . __( 'Data type', 'ultimate-member' ) . ': - ' . __( 'CHAR', 'ultimate-member' ) . ' - ' . __( 'NUMERIC', 'ultimate-member' ) . ' - ' . __( 'BINARY', 'ultimate-member' ) . ' - ' . __( 'DATE', 'ultimate-member' ) . ' - ' . __( 'DATETIME', 'ultimate-member' ) . ' - ' . __( 'DECIMAL', 'ultimate-member' ) . ' - ' . __( 'SIGNED', 'ultimate-member' ) . ' - ' . __( 'TIME', 'ultimate-member' ) . ' - ' . __( 'UNSIGNED', 'ultimate-member' ) . ' - + ' . __( 'Data type', 'ultimate-member' ) . ': ' . + $data_types_html . + ' ' . __( 'Order', 'ultimate-member' ) . ': ' . __( 'ASC', 'ultimate-member' ) . ' ' . __( 'DESC', 'ultimate-member' ) . ' diff --git a/includes/admin/templates/directory/sorting.php b/includes/admin/templates/directory/sorting.php index 6a33522b..9a9566d0 100644 --- a/includes/admin/templates/directory/sorting.php +++ b/includes/admin/templates/directory/sorting.php @@ -7,18 +7,6 @@ global $post_id; $_um_sorting_fields = get_post_meta( $post_id, '_um_sorting_fields', true ); $_um_sorting_fields = empty( $_um_sorting_fields ) ? array() : $_um_sorting_fields; -$custom_type_options = array( - 'CHAR' => 'CHAR', - 'NUMERIC' => 'NUMERIC', - 'BINARY' => 'BINARY', - 'DATE' => 'DATE', - 'DATETIME' => 'DATETIME', - 'DECIMAL' => 'DECIMAL', - 'SIGNED' => 'SIGNED', - 'TIME' => 'TIME', - 'UNSIGNED' => 'UNSIGNED', -); - $fields = array( array( 'id' => '_um_sortby', @@ -42,7 +30,7 @@ $fields = array( 'label' => __( 'Data type', 'ultimate-member' ), 'tooltip' => __( 'To correct sort by a custom field, choose a data type', 'ultimate-member' ), 'value' => UM()->query()->get_meta_value( '_um_sortby_custom_type', null, 'CHAR' ), - 'options' => $custom_type_options, + 'options' => UM()->member_directory()->sort_data_types, 'conditional' => array( '_um_sortby', '=', 'other' ), ), array( @@ -52,8 +40,8 @@ $fields = array( 'tooltip' => __( 'To correct sort by a custom field, choose an order', 'ultimate-member' ), 'value' => UM()->query()->get_meta_value( '_um_sortby_custom_order', null, 'ASC' ), 'options' => array( - 'ASC' => 'ASC', - 'DESC' => 'DESC', + 'ASC' => __( 'ASC', 'ultimate-member' ), + 'DESC' => __( 'DESC', 'ultimate-member' ), ), 'conditional' => array( '_um_sortby', '=', 'other' ), ), diff --git a/includes/class-config.php b/includes/class-config.php index 1892d6fe..3273fa67 100644 --- a/includes/class-config.php +++ b/includes/class-config.php @@ -1,13 +1,12 @@ is_search = true; } - //filters $filter_query = array(); if ( ! empty( $directory_data['search_fields'] ) ) { @@ -638,7 +644,6 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) { } } - //unable default filter in case if we select other filters in frontend filters //if ( empty( $this->custom_filters_in_query ) ) { $default_filters = array(); @@ -676,7 +681,7 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) { if ( ! empty( UM()->builtin()->saved_fields ) ) { foreach ( UM()->builtin()->saved_fields as $key => $data ) { - if ( $key == '_um_last_login' ) { + if ( '_um_last_login' === $key ) { continue; } @@ -694,26 +699,26 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) { // handle sorting options // sort members by if ( $sortby == $directory_data['sortby_custom'] || in_array( $sortby, $custom_sort ) ) { - $custom_sort_order = ! empty( $directory_data['sortby_custom_order'] ) ? $directory_data['sortby_custom_order'] : 'CHAR'; + $custom_sort_order = ! empty( $directory_data['sortby_custom_order'] ) ? $directory_data['sortby_custom_order'] : 'ASC'; $this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_sort ON ( umm_sort.user_id = u.ID AND umm_sort.um_key = '{$sortby}' )"; - $custom_sort_type = ! empty( $directory_data['sortby_custom_type'] ) ? $directory_data['sortby_custom_type'] : 'CHAR'; + $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:disable WordPress.Security.NonceVerification -- already verified here + // phpcs:ignore WordPress.Security.NonceVerification -- already verified here $sorting = sanitize_text_field( $_POST['sorting'] ); - $sorting_fields = unserialize( $directory_data['sorting_fields'] ); - // phpcs:enable WordPress.Security.NonceVerification + $sorting_fields = maybe_unserialize( $directory_data['sorting_fields'] ); + foreach ( $sorting_fields as $field ) { if ( isset( $field[ $sorting ] ) ) { - $custom_sort_type = $field['type']; + $custom_sort_type = ! empty( $field['type'] ) ? $meta_query->get_cast_for_type( $field['type'] ) : 'CHAR'; $custom_sort_order = $field['order']; } } } - if ( 'NUMERIC' === $custom_sort_type ) { - $custom_sort_type = 'DECIMAL'; - } + + /** This filter is documented in includes/core/class-member-directory.php */ $custom_sort_type = apply_filters( 'um_member_directory_custom_sorting_type', $custom_sort_type, $sortby, $directory_data ); $this->sql_order = " ORDER BY CAST( umm_sort.um_value AS {$custom_sort_type} ) {$custom_sort_order} "; @@ -819,7 +824,6 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) { $this->sql_order = apply_filters( 'um_modify_sortby_parameter_meta', $this->sql_order, $sortby ); - $profiles_per_page = $directory_data['profiles_per_page']; if ( UM()->mobile()->isMobile() && isset( $directory_data['profiles_per_page_mobile'] ) ) { $profiles_per_page = $directory_data['profiles_per_page_mobile']; diff --git a/includes/core/class-member-directory.php b/includes/core/class-member-directory.php index 231f44dd..7d9c40af 100644 --- a/includes/core/class-member-directory.php +++ b/includes/core/class-member-directory.php @@ -1,20 +1,18 @@ sorting_supported_fields = apply_filters( 'um_members_directory_custom_field_types_supported_sorting', array( 'number' ) ); + $this->sort_data_types = array( + 'CHAR' => __( 'CHAR', 'ultimate-member' ), + 'NUMERIC' => __( 'NUMERIC', 'ultimate-member' ), + 'BINARY' => __( 'BINARY', 'ultimate-member' ), + 'DATE' => __( 'DATE', 'ultimate-member' ), + 'DATETIME' => __( 'DATETIME', 'ultimate-member' ), + 'DECIMAL' => __( 'DECIMAL', 'ultimate-member' ), + 'SIGNED' => __( 'SIGNED', 'ultimate-member' ), + 'TIME' => __( 'TIME', 'ultimate-member' ), + 'UNSIGNED' => __( 'UNSIGNED', 'ultimate-member' ), + ); + + $this->sort_data_types = apply_filters( 'um_members_directory_sort_data_types', $this->sort_data_types ); + if ( ! empty( UM()->builtin()->saved_fields ) ) { foreach ( UM()->builtin()->saved_fields as $key => $data ) { if ( $key == '_um_last_login' ) { @@ -1434,21 +1450,45 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) { unset( $this->query_args['order'] ); } elseif ( ( ! empty( $directory_data['sortby_custom'] ) && $sortby == $directory_data['sortby_custom'] ) || in_array( $sortby, $custom_sort ) ) { - $custom_sort_order = ! empty( $directory_data['sortby_custom_order'] ) ? $directory_data['sortby_custom_order'] : 'CHAR'; + $custom_sort_order = ! empty( $directory_data['sortby_custom_order'] ) ? $directory_data['sortby_custom_order'] : 'ASC'; - $custom_sort_type = ! empty( $directory_data['sortby_custom_type'] ) ? $directory_data['sortby_custom_type'] : 'CHAR'; + $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:disable WordPress.Security.NonceVerification -- already verified here + // phpcs:ignore WordPress.Security.NonceVerification -- already verified here $sorting = sanitize_text_field( $_POST['sorting'] ); - $sorting_fields = unserialize( $directory_data['sorting_fields'] ); - // phpcs:enable WordPress.Security.NonceVerification + $sorting_fields = maybe_serialize( $directory_data['sorting_fields'] ); + foreach ( $sorting_fields as $field ) { if ( isset( $field[ $sorting ] ) ) { - $custom_sort_type = $field['type']; + $custom_sort_type = ! empty( $field['type'] ) ? $meta_query->get_cast_for_type( $field['type'] ) : 'CHAR'; $custom_sort_order = $field['order']; } } } + /** + * Filters the sorting MySQL type in member directory custom sorting query. + * + * Note: Possible MySQL types are BINARY|CHAR|DATE|DATETIME|SIGNED|UNSIGNED|TIME|DECIMAL + * + * @since 2.1.3 + * @hook um_member_directory_custom_sorting_type + * + * @param {string} $custom_sort_type MySQL type to cast meta_value. 'CHAR' is default. + * @param {string} $sortby meta_key used for sorting. + * @param {array} $directory_data Member directory data. + * + * @return {string} MySQL type to cast meta_value. + * @example Change type to DATE by the directory ID and mete_key. + * function my_um_member_directory_custom_sorting_type( $custom_sort_type, $sortby, $directory_data ) { + * if ( '{selected member directory ID}' == $directory_data['form_id'] && '{custom_date_key}' === $sortby ) { + * $custom_sort_type = 'DATE'; + * } + * + * return $custom_sort_type; + * } + * add_filter( 'um_member_directory_custom_sorting_type', 'my_um_member_directory_custom_sorting_type', 10, 3 ); + */ $custom_sort_type = apply_filters( 'um_member_directory_custom_sorting_type', $custom_sort_type, $sortby, $directory_data ); $this->query_args['meta_query'][] = array( @@ -2643,10 +2683,7 @@ if ( ! class_exists( 'um\core\Member_Directory' ) ) { add_filter( 'get_meta_sql', array( &$this, 'change_meta_sql' ), 10, 6 ); add_filter( 'pre_user_query', array( &$this, 'pagination_changes' ), 10, 1 ); -//echo ''; -//print_r($this->query_args); -//echo ''; -//exit(); + $user_query = new \WP_User_Query( $this->query_args ); remove_filter( 'pre_user_query', array( &$this, 'pagination_changes' ), 10 );
'; -//print_r($this->query_args); -//echo '