- fixed vulnerability with uploading cover/profile photo for other user ID;

- re-written member directory meta queries;
- fixed search line additional slashes;
This commit is contained in:
nikitasinelnikov
2020-01-08 15:19:24 +02:00
parent f0e3bc9ef4
commit 2496825590
5 changed files with 309 additions and 489 deletions
+287 -479
View File
@@ -18,9 +18,12 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) {
/**
* @var string
*/
var $sql_where = '';
var $meta_iteration = 1;
var $joins = array();
var $where_clauses = array();
var $roles = array();
var $general_meta_joined = false;
var $sql_limit = '';
var $sql_order = '';
@@ -172,6 +175,246 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) {
}
/**
* @param $directory_data
* @param $field
* @param $value
* @param $i
* @param bool $is_default
*/
function handle_filter_query( $directory_data, $field, $value, $i, $is_default = false ) {
global $wpdb;
$blog_id = get_current_blog_id();
switch ( $field ) {
default:
$filter_type = $this->filter_types[ $field ];
/**
* UM hook
*
* @type filter
* @title um_query_args_{$field}__filter
* @description Change field's query for search at Members Directory
* @input_vars
* [{"var":"$field_query","type":"array","desc":"Field query"}]
* @change_log
* ["Since: 2.0"]
* @usage
* <?php add_filter( 'um_query_args_{$field}__filter_meta', 'function_name', 10, 4 ); ?>
* @example
* <?php
* add_filter( 'um_query_args_{$field}__filter_meta', 'my_query_args_filter', 10, 4 );
* function my_query_args_filter( $field_query ) {
* // your code here
* return $field_query;
* }
* ?>
*/
$skip_default = apply_filters( "um_query_args_{$field}__filter_meta", false, $this, $field, $value, $filter_type, $is_default );
if ( ! $skip_default ) {
switch ( $filter_type ) {
default:
do_action( "um_query_args_{$field}_{$filter_type}__filter_meta", $field, $value, $filter_type, $i, $is_default );
break;
case 'text':
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm{$i} ON umm{$i}.user_id = u.ID";
$value = trim( stripslashes( $value ) );
$this->where_clauses[] = $wpdb->prepare( "umm{$i}.um_key = %s AND umm{$i}.um_value = %s", $field, $value );
if ( ! $is_default ) {
$this->custom_filters_in_query[ $field ] = $value;
}
break;
case 'select':
if ( ! is_array( $value ) ) {
$value = array( $value );
}
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm{$i} ON umm{$i}.user_id = u.ID";
$values_array = array();
foreach ( $value as $single_val ) {
$single_val = stripslashes( $single_val );
$values_array[] = $wpdb->prepare( "umm{$i}.um_value LIKE %s", '%"' . trim( $single_val ) . '"%' );
$values_array[] = $wpdb->prepare( "umm{$i}.um_value LIKE %s", '%' . serialize( strval( trim( $single_val ) ) ) . '%' );
$values_array[] = $wpdb->prepare( "umm{$i}.um_value = %s", trim( $single_val ) );
if ( is_numeric( $single_val ) ) {
$values_array[] = $wpdb->prepare( "umm{$i}.um_value LIKE %s", '%' . serialize( intval( trim( $single_val ) ) ) . '%' );
}
}
$values = implode( ' OR ', $values_array );
$this->where_clauses[] = $wpdb->prepare( "( umm{$i}.um_key = %s AND ( {$values} ) )", $field );
if ( ! $is_default ) {
$this->custom_filters_in_query[ $field ] = $value;
}
break;
case 'slider':
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm{$i} ON umm{$i}.user_id = u.ID";
$min = min( $value );
$max = max( $value );
$this->where_clauses[] = $wpdb->prepare( "( umm{$i}.um_key = %s AND umm{$i}.um_value BETWEEN %d AND %d )", $field, $min, $max );
if ( ! $is_default ) {
$this->custom_filters_in_query[ $field ] = $value;
}
break;
case 'datepicker':
$offset = 0;
if ( ! $is_default ) {
if ( isset( $_POST['gmt_offset'] ) && is_numeric( $_POST['gmt_offset'] ) ) {
$offset = (int) $_POST['gmt_offset'];
}
} else {
$gmt_offset = get_post_meta( $directory_data['form_id'], '_um_search_filters_gmt', true );
if ( is_numeric( $gmt_offset ) ) {
$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
$from_date = date( 'Y/m/d', $from_date );
$to_date = date( 'Y/m/d', $to_date );
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm{$i} ON umm{$i}.user_id = u.ID";
$this->where_clauses[] = $wpdb->prepare( "( umm{$i}.um_key = %s AND umm{$i}.um_value BETWEEN %s AND %s )", $field, $from_date, $to_date );
if ( ! $is_default ) {
$this->custom_filters_in_query[ $field ] = array( $from_date, $to_date );
}
break;
case 'timepicker':
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm{$i} ON umm{$i}.user_id = u.ID";
if ( $value[0] == $value[1] ) {
$this->where_clauses[] = $wpdb->prepare( "( umm{$i}.um_key = %s AND umm{$i}.um_value = %s )", $field, $value[0] );
} else {
$this->where_clauses[] = $wpdb->prepare( "( umm{$i}.um_key = %s AND CAST( umm{$i}.um_value AS TIME ) BETWEEN %s AND %s )", $field, $value[0], $value[1] );
}
if ( ! $is_default ) {
$this->custom_filters_in_query[ $field ] = $value;
}
break;
}
}
break;
case 'role':
$value = array_map( 'strtolower', $value );
if ( empty( $this->roles ) && ! is_multisite() ) {
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_roles ON ( umm_roles.user_id = u.ID AND umm_roles.um_key = '" . $wpdb->get_blog_prefix( $blog_id ) . "capabilities' )";
$this->roles = $value;
}
$roles_clauses = array();
foreach ( $value as $role ) {
$roles_clauses[] = $wpdb->prepare( "umm_roles.um_value LIKE %s", '%"' . $role . '"%' );
}
$this->where_clauses[] = '( ' . implode( ' OR ', $roles_clauses ) . ' )';
if ( ! $is_default ) {
$this->custom_filters_in_query[ $field ] = $value;
}
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 ) ) );
$to_date = date( 'Y/m/d', mktime( 0,0,0, date( 'm', time() ), date( 'd', time() ) + 1, date( 'Y', time() - ( max( $value ) + 1 ) * YEAR_IN_SECONDS ) ) );
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm{$i} ON umm{$i}.user_id = u.ID";
$this->where_clauses[] = $wpdb->prepare( "( umm{$i}.um_key = 'birth_date' AND umm{$i}.um_value BETWEEN %s AND %s )", $from_date, $to_date );
if ( ! $is_default ) {
$this->custom_filters_in_query[ $field ] = array( $to_date, $from_date );
}
break;
case 'user_registered':
$offset = 0;
if ( ! $is_default ) {
if ( isset( $_POST['gmt_offset'] ) && is_numeric( $_POST['gmt_offset'] ) ) {
$offset = (int) $_POST['gmt_offset'];
}
} else {
$gmt_offset = get_post_meta( $directory_data['form_id'], '_um_search_filters_gmt', true );
if ( is_numeric( $gmt_offset ) ) {
$offset = $gmt_offset;
}
}
$from_date = date( 'Y-m-d H:s:i', strtotime( date( 'Y-m-d H:s:i', min( $value ) ) . "+$offset hours" ) );
$to_date = date( 'Y-m-d H:s:i', strtotime( date( 'Y-m-d H:s:i', max( $value ) ) . "+$offset hours" ) );
$this->where_clauses[] = $wpdb->prepare( "u.user_registered BETWEEN %s AND %s", $from_date, $to_date );
if ( ! $is_default ) {
$this->custom_filters_in_query[ $field ] = $value;
}
break;
case 'last_login':
$offset = 0;
if ( ! $is_default ) {
if ( isset( $_POST['gmt_offset'] ) && is_numeric( $_POST['gmt_offset'] ) ) {
$offset = (int) $_POST['gmt_offset'];
}
} else {
$gmt_offset = get_post_meta( $directory_data['form_id'], '_um_search_filters_gmt', true );
if ( is_numeric( $gmt_offset ) ) {
$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
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm{$i} ON umm{$i}.user_id = u.ID";
$this->where_clauses[] = $wpdb->prepare( "( umm{$i}.um_key = '_um_last_login' AND umm{$i}.um_value BETWEEN %s AND %s )", $from_date, $to_date );
if ( ! $is_default ) {
$this->custom_filters_in_query[ $field ] = $value;
}
break;
}
}
/**
* Main Query function for getting members via AJAX
*/
@@ -206,7 +449,7 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) {
}
if ( ! empty( $users_array ) ) {
$this->sql_where .= " AND u.ID IN ( '" . implode( "','", $users_array ) . "' )";
$this->where_clauses[] = "u.ID IN ( '" . implode( "','", $users_array ) . "' )";
}
}
}
@@ -223,19 +466,23 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) {
}
if ( ! UM()->roles()->um_user_can( 'can_edit_everyone' ) ) {
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_general ON umm_general.user_id = u.ID";
$this->sql_where .= " AND ( umm_general.um_key = 'um_member_directory_data' AND
if ( ! $this->general_meta_joined ) {
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_general ON umm_general.user_id = u.ID";
$this->general_meta_joined = true;
}
$this->where_clauses[] = "( umm_general.um_key = 'um_member_directory_data' AND
umm_general.um_value LIKE '%s:14:\"account_status\";s:8:\"approved\";%' AND umm_general.um_value LIKE '%s:15:\"hide_in_members\";b:0;%'{$profile_photo_where}{$cover_photo_where} )";
} else {
if ( ! empty( $cover_photo_where ) || ! empty( $profile_photo_where ) ) {
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_general ON umm_general.user_id = u.ID";
$this->sql_where .= " AND ( umm_general.um_key = 'um_member_directory_data'{$profile_photo_where}{$cover_photo_where} )";
if ( ! $this->general_meta_joined ) {
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_general ON umm_general.user_id = u.ID";
$this->general_meta_joined = true;
}
$this->where_clauses[] = "( umm_general.um_key = 'um_member_directory_data'{$profile_photo_where}{$cover_photo_where} )";
}
}
$roles = array();
//$this->roles = array();
if ( UM()->roles()->um_user_can( 'can_view_all' ) ) {
$view_roles = um_user( 'can_view_roles' );
@@ -243,47 +490,48 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) {
$view_roles = array();
}
$roles = array_merge( $roles, maybe_unserialize( $view_roles ) );
$this->roles = array_merge( $this->roles, maybe_unserialize( $view_roles ) );
}
if ( ! empty( $directory_data['roles'] ) ) {
if ( ! empty( $roles ) ) {
$roles = array_intersect( $roles, maybe_unserialize( $directory_data['roles'] ) );
if ( ! empty( $this->roles ) ) {
$this->roles = array_intersect( $this->roles, maybe_unserialize( $directory_data['roles'] ) );
} else {
$roles = array_merge( $roles, maybe_unserialize( $directory_data['roles'] ) );
$this->roles = array_merge( $this->roles, maybe_unserialize( $directory_data['roles'] ) );
}
}
if ( ! empty( $roles ) ) {
if ( ! empty( $this->roles ) ) {
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_roles ON ( umm_roles.user_id = u.ID AND umm_roles.um_key = '" . $wpdb->get_blog_prefix( $blog_id ) . "capabilities' )";
$roles_clauses = array();
foreach ( $roles as $role ) {
$roles_clauses[] = "umm_roles.um_value LIKE '%\"" . $role . "\"%'";
foreach ( $this->roles as $role ) {
$roles_clauses[] = $wpdb->prepare( 'umm_roles.um_value LIKE %s', '%"' . $role . '"%' );
}
$roles_search = implode( ' OR ', $roles_clauses );
$this->sql_where .= " AND ( {$roles_search} )";
$this->where_clauses[] = '( ' . implode( ' OR ', $roles_clauses ) . ' )';
} else {
if ( is_multisite() ) {
// select users who have capabilities for current blog
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_roles ON ( umm_roles.user_id = u.ID AND umm_roles.um_key = '" . $wpdb->get_blog_prefix( $blog_id ) . "capabilities' )";
$this->sql_where .= " AND umm_roles.um_value IS NOT NULL ";
$this->where_clauses[] = "umm_roles.um_value IS NOT NULL";
}
}
if ( ! empty( $_POST['search'] ) ) {
$search_line = trim( stripslashes( $_POST['search'] ) );
$searches = array();
foreach ( $this->core_search_fields as $field ) {
$searches[] = $wpdb->prepare( "u.{$field} LIKE %s", '%' . trim( $_POST['search'] ) . '%' );
$searches[] = $wpdb->prepare( "u.{$field} LIKE %s", '%' . $search_line . '%' );
}
$core_search = implode( ' OR ', $searches );
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_search ON umm_search.user_id = u.ID";
$this->sql_where .= " AND ( umm_search.um_value = '" . trim( $_POST['search'] ) . "' OR umm_search.um_value LIKE '%" . trim( $_POST['search'] ) . "%' OR umm_search.um_value LIKE '%" . trim( serialize( strval( $_POST['search'] ) ) ) . "%' OR {$core_search})";
$this->where_clauses[] = $wpdb->prepare( "( umm_search.um_value = %s OR umm_search.um_value LIKE %s OR umm_search.um_value LIKE %s OR {$core_search})", $search_line, '%' . $search_line . '%', '%' . serialize( strval( $search_line ) ) . '%' );
$this->is_search = true;
}
@@ -313,209 +561,7 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) {
continue;
}
switch ( $field ) {
default:
$filter_type = $this->filter_types[ $field ];
/**
* UM hook
*
* @type filter
* @title um_query_args_{$field}__filter
* @description Change field's query for search at Members Directory
* @input_vars
* [{"var":"$field_query","type":"array","desc":"Field query"}]
* @change_log
* ["Since: 2.0"]
* @usage
* <?php add_filter( 'um_query_args_{$field}__filter', 'function_name', 10, 1 ); ?>
* @example
* <?php
* add_filter( 'um_query_args_{$field}__filter', 'my_query_args_filter', 10, 1 );
* function my_query_args_filter( $field_query ) {
* // your code here
* return $field_query;
* }
* ?>
*/
$field_query = apply_filters( "um_query_args_{$field}__filter", false, $field, $value, $filter_type );
if ( ! $field_query ) {
switch ( $filter_type ) {
default:
$field_query = apply_filters( "um_query_args_{$field}_{$filter_type}__filter", false, $field, $value, $filter_type );
break;
case 'text':
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID";
$value = trim( stripslashes( $value ) );
$this->sql_where .= " AND ( umm" . $i . ".um_key = '{$field}' AND umm" . $i . ".um_value = '{$value}' )";
$this->custom_filters_in_query[ $field ] = $value;
break;
case 'select':
if ( is_array( $value ) ) {
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID";
$values_array = array();
foreach ( $value as $single_val ) {
$single_val = stripslashes( $single_val );
$values_array[] = "umm" . $i . ".um_value LIKE '%\"" . trim( $single_val ) . "\"%'";
$values_array[] = "umm" . $i . ".um_value LIKE '%" . serialize( strval( trim( $single_val ) ) ) . "%'";
$values_array[] = "umm" . $i . ".um_value = '" . trim( $single_val ) . "'";
if ( is_numeric( $single_val ) ) {
$values_array[] = "umm" . $i . ".um_value LIKE '%" . serialize( intval( trim( $single_val ) ) ) . "%'";
}
}
$values = implode( ' OR ', $values_array );
$this->sql_where .= " AND ( umm" . $i . ".um_key = '{$field}' AND ( {$values} ) )";
}
$this->custom_filters_in_query[ $field ] = $value;
break;
case 'slider':
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID";
$min = min( $value );
$max = max( $value );
$this->sql_where .= " AND ( umm" . $i . ".um_key = '{$field}' AND umm" . $i . ".um_value BETWEEN {$min} AND {$max} )";
$this->custom_filters_in_query[ $field ] = $value;
break;
case 'datepicker':
$offset = 0;
if ( isset( $_POST['gmt_offset'] ) && is_numeric( $_POST['gmt_offset'] ) ) {
$offset = (int) $_POST['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
$from_date = date( 'Y/m/d', $from_date );
$to_date = date( 'Y/m/d', $to_date );
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID";
$this->sql_where .= " AND ( umm" . $i . ".um_key = '{$field}' AND umm" . $i . ".um_value BETWEEN {$from_date} AND {$to_date} )";
$this->custom_filters_in_query[ $field ] = array( $from_date, $to_date );
break;
case 'timepicker':
if ( $value[0] == $value[1] ) {
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID";
$this->sql_where .= " AND ( umm" . $i . ".um_key = '{$field}' AND umm" . $i . ".um_value = '{$value[0]}' )";
} else {
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID";
$this->sql_where .= " AND ( umm" . $i . ".um_key = '{$field}' AND CAST( umm" . $i . ".um_value AS TIME ) BETWEEN {$value[0]} AND {$value[1]} )";
}
$this->custom_filters_in_query[ $field ] = $value;
break;
}
}
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( $roles ) || is_multisite() ) {
$roles_clauses = array();
foreach ( $value as $role ) {
$roles_clauses[] = "umm_roles.um_value LIKE '%\"" . $role . "\"%'";
}
$roles_search = implode( ' OR ', $roles_clauses );
$this->sql_where .= " AND ( {$roles_search} )";
} else {
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_roles ON ( umm_roles.user_id = u.ID AND umm_roles.um_key = '" . $wpdb->get_blog_prefix( $blog_id ) . "capabilities' )";
$roles = $value;
$roles_clauses = array();
foreach ( $value as $role ) {
$roles_clauses[] = "umm_roles.um_value LIKE '%\"" . $role . "\"%'";
}
$roles_search = implode( ' OR ', $roles_clauses );
$this->sql_where .= " AND ( {$roles_search} )";
}
$this->custom_filters_in_query[ $field ] = $value;
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 ) ) );
$to_date = date( 'Y/m/d', mktime( 0,0,0, date( 'm', time() ), date( 'd', time() ) + 1, date( 'Y', time() - ( max( $value ) + 1 ) * YEAR_IN_SECONDS ) ) );
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID";
$this->sql_where .= " AND ( umm" . $i . ".um_key = 'birth_date' AND umm" . $i . ".um_value BETWEEN {$from_date} AND {$to_date} )";
$this->custom_filters_in_query[ $field ] = array( $to_date, $from_date );
break;
case 'user_registered':
$offset = 0;
if ( isset( $_POST['gmt_offset'] ) && is_numeric( $_POST['gmt_offset'] ) ) {
$offset = (int) $_POST['gmt_offset'];
}
$from_date = date( 'Y-m-d H:s:i', strtotime( date( 'Y-m-d H:s:i', min( $value ) ) . "+$offset hours" ) );
$to_date = date( 'Y-m-d H:s:i', strtotime( date( 'Y-m-d H:s:i', max( $value ) ) . "+$offset hours" ) );
$this->sql_where .= " AND ( u.user_registered BETWEEN {$from_date} AND {$to_date} )";
$this->custom_filters_in_query[ $field ] = $value;
break;
case 'last_login':
$offset = 0;
if ( isset( $_POST['gmt_offset'] ) && is_numeric( $_POST['gmt_offset'] ) ) {
$offset = (int) $_POST['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
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm" . $i . " ON umm" . $i . ".user_id = u.ID";
$this->sql_where .= " AND ( umm" . $i . ".um_key = '_um_last_login' AND umm" . $i . ".um_value BETWEEN {$from_date} AND {$to_date} )";
$this->custom_filters_in_query[ $field ] = $value;
break;
}
$this->handle_filter_query( $directory_data, $field, $value, $i );
$i++;
}
@@ -529,199 +575,11 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) {
$default_filters = maybe_unserialize( $directory_data['search_filters'] );
}
$gmt_offset = get_post_meta( $directory_data['form_id'], '_um_search_filters_gmt', true );
if ( ! empty( $default_filters ) ) {
$i = 1;
foreach ( $default_filters as $field => $value ) {
//unable default filter in case if we select other value in frontend filters
// if ( in_array( $field, array_keys( $this->custom_filters_in_query ) ) ) {
// continue;
// }
switch ( $field ) {
default:
$filter_type = $this->filter_types[ $field ];
/**
* UM hook
*
* @type filter
* @title um_query_args_{$field}__filter
* @description Change field's query for search at Members Directory
* @input_vars
* [{"var":"$field_query","type":"array","desc":"Field query"}]
* @change_log
* ["Since: 2.0"]
* @usage
* <?php add_filter( 'um_query_args_{$field}__filter', 'function_name', 10, 1 ); ?>
* @example
* <?php
* add_filter( 'um_query_args_{$field}__filter', 'my_query_args_filter', 10, 1 );
* function my_query_args_filter( $field_query ) {
* // your code here
* return $field_query;
* }
* ?>
*/
$field_query = apply_filters( "um_query_args_{$field}__filter", false, $field, $value, $filter_type );
if ( ! $field_query ) {
switch ( $filter_type ) {
default:
$field_query = apply_filters( "um_query_args_{$field}_{$filter_type}__filter", false, $field, $value, $filter_type );
break;
case 'text':
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID";
$value = trim( stripslashes( $value ) );
$this->sql_where .= " AND ( ummd" . $i . ".um_key = '{$field}' AND ummd" . $i . ".um_value = '{$value}' )";
$this->custom_filters_in_query[ $field ] = $value;
break;
case 'select':
if ( ! is_array( $value ) ) {
$value = array( $value );
}
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID";
$values_array = array();
foreach ( $value as $single_val ) {
$single_val = stripslashes( $single_val );
$values_array[] = "ummd" . $i . ".um_value LIKE '%\"" . trim( $single_val ) . "\"%'";
$values_array[] = "ummd" . $i . ".um_value LIKE '%" . serialize( strval( trim( $single_val ) ) ) . "%'";
$values_array[] = "ummd" . $i . ".um_value = '" . trim( $single_val ) . "'";
if ( is_numeric( $single_val ) ) {
$values_array[] = "ummd" . $i . ".um_value LIKE '%" . serialize( intval( trim( $single_val ) ) ) . "%'";
}
}
$values = implode( ' OR ', $values_array );
$this->sql_where .= " AND ( ummd" . $i . ".um_key = '{$field}' AND ( {$values} ) )";
break;
case 'slider':
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID";
$min = min( $value );
$max = max( $value );
$this->sql_where .= " AND ( ummd" . $i . ".um_key = '{$field}' AND ummd" . $i . ".um_value BETWEEN {$min} AND {$max} )";
break;
case 'datepicker':
$offset = 0;
if ( is_numeric( $gmt_offset ) ) {
$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
$from_date = date( 'Y/m/d', $from_date );
$to_date = date( 'Y/m/d', $to_date );
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID";
$this->sql_where .= " AND ( ummd" . $i . ".um_key = '{$field}' AND ummd" . $i . ".um_value BETWEEN {$from_date} AND {$to_date} )";
break;
case 'timepicker':
if ( $value[0] == $value[1] ) {
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID";
$this->sql_where .= " AND ( ummd" . $i . ".um_key = '{$field}' AND ummd" . $i . ".um_value = '{$value[0]}' )";
} else {
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID";
$this->sql_where .= " AND ( ummd" . $i . ".um_key = '{$field}' AND CAST( ummd" . $i . ".um_value AS TIME ) BETWEEN {$value[0]} AND {$value[1]} )";
}
break;
}
}
break;
case 'role':
// $value = explode( '||', $value );
// $value = array_map( 'strtolower', $value );
$value = array_map( 'strtolower', $value );
if ( ! empty( $roles ) || is_multisite() ) {
$roles_clauses = array();
foreach ( $value as $role ) {
$roles_clauses[] = "umm_roles.um_value LIKE '%\"" . $role . "\"%'";
}
$roles_search = implode( ' OR ', $roles_clauses );
$this->sql_where .= " AND ( {$roles_search} )";
} else {
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata umm_roles ON ( umm_roles.user_id = u.ID AND umm_roles.um_key = '" . $wpdb->get_blog_prefix( $blog_id ) . "capabilities' )";
$roles = $value;
$roles_clauses = array();
foreach ( $value as $role ) {
$roles_clauses[] = "umm_roles.um_value LIKE '%\"" . $role . "\"%'";
}
$roles_search = implode( ' OR ', $roles_clauses );
$this->sql_where .= " AND ( {$roles_search} )";
}
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 ) ) );
$to_date = date( 'Y/m/d', mktime( 0,0,0, date( 'm', time() ), date( 'd', time() ) + 1, date( 'Y', time() - ( max( $value ) + 1 ) * YEAR_IN_SECONDS ) ) );
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID";
$this->sql_where .= " AND ( ummd" . $i . ".um_key = 'birth_date' AND ummd" . $i . ".um_value BETWEEN {$from_date} AND {$to_date} )";
break;
case 'user_registered':
$offset = 0;
if ( is_numeric( $gmt_offset ) ) {
$offset = $gmt_offset;
}
$from_date = date( 'Y-m-d H:s:i', strtotime( date( 'Y-m-d H:s:i', min( $value ) ) . "+$offset hours" ) );
$to_date = date( 'Y-m-d H:s:i', strtotime( date( 'Y-m-d H:s:i', max( $value ) ) . "+$offset hours" ) );
$this->sql_where .= " AND ( u.user_registered BETWEEN {$from_date} AND {$to_date} )";
break;
case 'last_login':
$offset = 0;
if ( is_numeric( $gmt_offset ) ) {
$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
$this->joins[] = "LEFT JOIN {$wpdb->prefix}um_metadata ummd" . $i . " ON ummd" . $i . ".user_id = u.ID";
$this->sql_where .= " AND ( ummd" . $i . ".um_key = '_um_last_login' AND ummd" . $i . ".um_value BETWEEN {$from_date} AND {$to_date} )";
break;
}
$this->handle_filter_query( $directory_data, $field, $value, $i, true );
$i++;
}
@@ -820,7 +678,7 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) {
}
}
$this->sql_order = apply_filters( 'um_modify_sortby_parameter', $this->sql_order, $sortby );
$this->sql_order = apply_filters( 'um_modify_sortby_parameter_meta', $this->sql_order, $sortby );
$profiles_per_page = $directory_data['profiles_per_page'];
@@ -841,16 +699,26 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) {
$this->sql_limit .= $wpdb->prepare( 'LIMIT %d, %d', $query_number * ( $query_paged - 1 ), $number );
}
$sql_join = implode( ' ', $this->joins );
do_action( 'um_pre_users_query', $this, $directory_data, $sortby );
$sql_join = implode( ' ', $this->joins );
$sql_where = implode( ' AND ', $this->where_clauses );
$sql_where = ! empty( $sql_where ) ? ' AND ' . $sql_where : '';
global $wpdb;
/*var_dump( "SELECT SQL_CALC_FOUND_ROWS DISTINCT u.ID
FROM {$wpdb->users} AS u
{$sql_join}
WHERE 1=1 {$sql_where}
{$this->sql_order}
{$this->sql_limit}" );*/
$user_ids = $wpdb->get_col(
"SELECT SQL_CALC_FOUND_ROWS DISTINCT u.ID
FROM {$wpdb->users} AS u
{$sql_join}
WHERE 1=1 {$this->sql_where}
WHERE 1=1 {$sql_where}
{$this->sql_order}
{$this->sql_limit}"
);
@@ -876,65 +744,5 @@ if ( ! class_exists( 'um\core\Member_Directory_Meta' ) ) {
wp_send_json_success( array( 'pagination' => $pagination_data, 'users' => $users, 'is_search' => $this->is_search ) );
}
/**
* Get data array for pagination
*
*
* @param array $directory_data
* @param int $total_users
*
* @return array
*/
function calculate_pagination( $directory_data, $total_users ) {
$current_page = ! empty( $_POST['page'] ) ? $_POST['page'] : 1;
$total_users = ( ! empty( $directory_data['max_users'] ) && $directory_data['max_users'] <= $total_users ) ? $directory_data['max_users'] : $total_users;
// number of profiles for mobile
$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'];
}
$total_pages = 1;
if ( ! empty( $profiles_per_page ) ) {
$total_pages = ceil( $total_users / $profiles_per_page );
}
if ( ! empty( $total_pages ) ) {
$index1 = 0 - ( $current_page - 2 ) + 1;
$to = $current_page + 2;
if ( $index1 > 0 ) {
$to += $index1;
}
$index2 = $total_pages - ( $current_page + 2 );
$from = $current_page - 2;
if ( $index2 < 0 ) {
$from += $index2;
}
$pages_to_show = range(
( $from > 0 ) ? $from : 1,
( $to <= $total_pages ) ? $to : $total_pages
);
}
$pagination_data = array(
'pages_to_show' => ( ! empty( $pages_to_show ) && count( $pages_to_show ) > 1 ) ? array_values( $pages_to_show ) : array(),
'current_page' => $current_page,
'total_pages' => $total_pages,
'total_users' => $total_users,
);
$pagination_data['header'] = $this->convert_tags( $directory_data['header'], $pagination_data );
$pagination_data['header_single'] = $this->convert_tags( $directory_data['header_single'], $pagination_data );
return $pagination_data;
}
}
}