mirror of
https://github.com/10h30/ultimatemember.git
synced 2026-06-05 15:09:37 +09:00
7014623010
Updated regular expressions to strengthen protection against sleep and benchmark injection attacks. This change improves the security of queries by handling potential edge cases more effectively.
3109 lines
97 KiB
PHP
3109 lines
97 KiB
PHP
<?php
|
|
namespace um\core;
|
|
|
|
use WP_User_Query;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
if ( ! class_exists( 'um\core\Member_Directory' ) ) {
|
|
|
|
/**
|
|
* Class Member_Directory
|
|
* @package um\core
|
|
*/
|
|
class Member_Directory {
|
|
|
|
/**
|
|
* Member Directory Views
|
|
*
|
|
* @var array
|
|
*/
|
|
var $view_types = array();
|
|
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
var $sort_fields = array();
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
var $sort_data_types = array();
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
var $default_sorting = array();
|
|
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
var $filter_fields = array();
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
public $searching_fields = array();
|
|
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
var $custom_filters_in_query = array();
|
|
|
|
|
|
|
|
var $filter_supported_fields = array();
|
|
|
|
|
|
var $sorting_supported_fields = array();
|
|
|
|
|
|
var $filter_types = array();
|
|
|
|
/**
|
|
* Fields used for searching from wp_users table.
|
|
*
|
|
* @var string[]
|
|
*/
|
|
var $core_search_fields = array(
|
|
'user_login',
|
|
'user_url',
|
|
'display_name',
|
|
'user_email',
|
|
'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
|
|
*/
|
|
var $query_args;
|
|
|
|
|
|
/**
|
|
* @var User Card cover size
|
|
*/
|
|
var $cover_size;
|
|
|
|
|
|
/**
|
|
* @var User Avatar size
|
|
*/
|
|
var $avatar_size;
|
|
|
|
|
|
/**
|
|
* @var bool Searching marker
|
|
*/
|
|
var $is_search = false;
|
|
|
|
|
|
/**
|
|
* Member_Directory constructor.
|
|
*/
|
|
public function __construct() {
|
|
add_filter( 'init', array( &$this, 'init_variables' ) );
|
|
|
|
add_action( 'template_redirect', array( &$this, 'access_members' ), 555 );
|
|
}
|
|
|
|
/**
|
|
* Get the WordPress core searching fields in wp_users query.
|
|
* @return array
|
|
*/
|
|
protected function get_core_search_fields() {
|
|
/**
|
|
* Filters the WordPress core searching fields in wp_users query for UM Member directory query.
|
|
*
|
|
* @param {array} $core_search_fields Core search fields in wp_users query.
|
|
*
|
|
* @return {array} Core search fields in wp_users query.
|
|
*
|
|
* @since 2.6.10
|
|
* @hook um_member_directory_core_search_fields
|
|
*
|
|
* @example <caption>Extends or remove wp_users core search fields.</caption>
|
|
* function my_um_member_directory_core_search_fields( $core_search_fields ) {
|
|
* $core_search_fields = array_flip( $core_search_fields );
|
|
* unset( $core_search_fields['user_email'] );
|
|
* $core_search_fields = array_flip( $core_search_fields );
|
|
* return $core_search_fields;
|
|
* }
|
|
* add_filter( 'um_member_directory_core_search_fields', 'my_um_member_directory_core_search_fields' );
|
|
*/
|
|
return apply_filters( 'um_member_directory_core_search_fields', $this->core_search_fields );
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
function get_hide_in_members_default() {
|
|
$default = false;
|
|
$option = UM()->options()->get( 'account_hide_in_directory_default' );
|
|
if ( $option == 'Yes' ) {
|
|
$default = true;
|
|
}
|
|
|
|
$default = apply_filters( 'um_member_directory_hide_in_members_default', $default );
|
|
return $default;
|
|
}
|
|
|
|
|
|
/**
|
|
* Getting member directory post ID via hash
|
|
* Hash is unique attr, which we use visible at frontend
|
|
*
|
|
* @param string $hash
|
|
*
|
|
* @return bool|int
|
|
*/
|
|
function get_directory_by_hash( $hash ) {
|
|
global $wpdb;
|
|
|
|
$directory_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE SUBSTRING( MD5( ID ), 11, 5 ) = %s", $hash ) );
|
|
|
|
if ( empty( $directory_id ) ) {
|
|
return false;
|
|
}
|
|
|
|
return (int) $directory_id;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $id
|
|
*
|
|
* @return bool|string
|
|
*/
|
|
function get_directory_hash( $id ) {
|
|
$hash = substr( md5( $id ), 10, 5 );
|
|
return $hash;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get view Type template
|
|
* @param string $type
|
|
*
|
|
* @return string
|
|
*/
|
|
function get_type_basename( $type ) {
|
|
return apply_filters( "um_member_directory_{$type}_type_template_basename", '' );
|
|
}
|
|
|
|
|
|
/**
|
|
* Tag conversion for member directory
|
|
*
|
|
* @param string $string
|
|
* @param array $array
|
|
*
|
|
* @return string
|
|
*/
|
|
function convert_tags( $string, $array ) {
|
|
|
|
$search = array(
|
|
'{total_users}',
|
|
);
|
|
|
|
$replace = array(
|
|
$array['total_users'],
|
|
);
|
|
|
|
$string = str_replace( $search, $replace, $string );
|
|
return $string;
|
|
}
|
|
|
|
|
|
/**
|
|
* Members page allowed?
|
|
*
|
|
* can be disabled by "Enable Members Directory" option
|
|
*
|
|
*/
|
|
public function access_members() {
|
|
if ( um_is_predefined_page( 'members' ) && ! UM()->options()->get( 'members_page' ) ) {
|
|
um_redirect_home();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $value
|
|
* @param $key
|
|
* @param $post_id
|
|
*
|
|
* @return array
|
|
*/
|
|
public function before_save_data( $value, $key, $post_id ) {
|
|
$post = get_post( $post_id );
|
|
|
|
if ( 'um_directory' !== $post->post_type ) {
|
|
return $value;
|
|
}
|
|
|
|
if ( ! empty( $value ) && in_array( $key, array( '_um_view_types', '_um_roles', '_um_roles_can_search', '_um_roles_can_filter' ), true ) ) {
|
|
$value = array_keys( $value );
|
|
} elseif ( '_um_search_filters' === $key ) {
|
|
$temp_value = array();
|
|
|
|
// phpcs:disable WordPress.Security.NonceVerification -- already verified here
|
|
if ( ! empty( $value ) ) {
|
|
foreach ( $value as $k ) {
|
|
$filter_type = $this->filter_types[ $k ];
|
|
if ( ! empty( $filter_type ) ) {
|
|
if ( 'slider' === $filter_type ) {
|
|
if ( ! empty( $_POST[ $k ] ) ) {
|
|
if ( count( $_POST[ $k ] ) > 1 ) {
|
|
$temp_value[ $k ] = array_map( 'intval', $_POST[ $k ] );
|
|
} else {
|
|
$temp_value[ $k ] = (int) $_POST[ $k ];
|
|
}
|
|
}
|
|
} elseif ( 'datepicker' === $filter_type ) {
|
|
if ( ! empty( $_POST[ $k . '_from' ] ) ) {
|
|
$temp_value[ $k ][0] = sanitize_text_field( $_POST[ $k . '_from' ] );
|
|
}
|
|
if ( ! empty( $_POST[ $k . '_to' ] ) ) {
|
|
$temp_value[ $k ][1] = sanitize_text_field( $_POST[ $k . '_to' ] );
|
|
}
|
|
} elseif ( 'timepicker' === $filter_type ) {
|
|
if ( ! empty( $_POST[ $k . '_from' ] ) ) {
|
|
$temp_value[ $k ][0] = sanitize_text_field( $_POST[ $k . '_from' ] );
|
|
}
|
|
if ( ! empty( $_POST[ $k . '_to' ] ) ) {
|
|
$temp_value[ $k ][1] = sanitize_text_field( $_POST[ $k . '_to' ] );
|
|
}
|
|
} elseif ( 'select' === $filter_type ) {
|
|
if ( ! empty( $_POST[ $k ] ) ) {
|
|
if ( is_array( $_POST[ $k ] ) ) {
|
|
$temp_value[ $k ] = array_map( 'trim', $_POST[ $k ] );
|
|
} else {
|
|
$temp_value[ $k ] = array( trim( $_POST[ $k ] ) );
|
|
}
|
|
|
|
$temp_value[ $k ] = array_map( 'sanitize_text_field', $temp_value[ $k ] );
|
|
}
|
|
} else {
|
|
if ( ! empty( $_POST[ $k ] ) ) {
|
|
$temp_value[ $k ] = trim( sanitize_text_field( $_POST[ $k ] ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$value = $temp_value;
|
|
|
|
// phpcs:enable WordPress.Security.NonceVerification -- already verified here
|
|
} elseif ( '_um_sorting_fields' === $key ) {
|
|
if ( ! empty( $value['other_data'] ) ) {
|
|
$other_data = $value['other_data'];
|
|
unset( $value['other_data'] );
|
|
|
|
foreach ( $value as $k => &$row ) {
|
|
if ( ! empty( $other_data[ $k ]['meta_key'] ) ) {
|
|
$metakey = sanitize_text_field( $other_data[ $k ]['meta_key'] );
|
|
if ( ! empty( $metakey ) ) {
|
|
if ( ! empty( $other_data[ $k ]['label'] ) ) {
|
|
$metalabel = wp_strip_all_tags( $other_data[ $k ]['label'] );
|
|
}
|
|
if ( ! empty( $other_data[ $k ]['data_type'] ) ) {
|
|
$data_type = sanitize_text_field( $other_data[ $k ]['data_type'] );
|
|
}
|
|
if ( ! empty( $other_data[ $k ]['order'] ) ) {
|
|
$order = sanitize_text_field( $other_data[ $k ]['order'] );
|
|
}
|
|
$row = array(
|
|
$metakey => $metakey,
|
|
'label' => ! empty( $metalabel ) ? $metalabel : $metakey,
|
|
'type' => ! empty( $data_type ) ? $data_type : '',
|
|
'order' => ! empty( $order ) ? $order : '',
|
|
);
|
|
}
|
|
}
|
|
}
|
|
unset( $row );
|
|
}
|
|
} elseif ( '_um_sortby_custom' === $key ) {
|
|
$value = sanitize_text_field( $value );
|
|
} elseif ( '_um_sortby_custom_label' === $key ) {
|
|
$value = wp_strip_all_tags( $value );
|
|
} elseif ( '_um_sortby_custom_type' === $key ) {
|
|
$value = sanitize_text_field( $value );
|
|
} elseif ( '_um_sortby_custom_order' === $key ) {
|
|
$value = sanitize_text_field( $value );
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
function init_variables() {
|
|
|
|
// Types
|
|
$this->view_types = apply_filters( 'um_member_directory_views', array(
|
|
'grid' => array( 'title' => __( 'Grid', 'ultimate-member' ), 'icon' => 'um-faicon-th' ),
|
|
'list' => array( 'title' => __( 'List', 'ultimate-member' ), 'icon' => 'um-faicon-list' ),
|
|
) );
|
|
|
|
// Sort
|
|
$this->sort_fields = apply_filters( 'um_members_directory_sort_fields', array(
|
|
'user_registered_desc' => __( 'New users first', 'ultimate-member' ),
|
|
'user_registered_asc' => __( 'Old users first', 'ultimate-member' ),
|
|
'username' => __( 'Username', 'ultimate-member' ),
|
|
'nickname' => __( 'Nickname', 'ultimate-member' ),
|
|
'first_name' => __( 'First name', 'ultimate-member' ),
|
|
'last_name' => __( 'Last name', 'ultimate-member' ),
|
|
'display_name' => __( 'Display name', 'ultimate-member' ),
|
|
'last_first_name' => __( 'Last & First name', 'ultimate-member' ),
|
|
'last_login' => __( 'Last login', 'ultimate-member' ),
|
|
) );
|
|
|
|
$this->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 ( '_um_last_login' === $key ) {
|
|
continue;
|
|
}
|
|
|
|
if ( isset( $data['type'] ) && in_array( $data['type'], $this->sorting_supported_fields ) ) {
|
|
// translators: %s: title.
|
|
if ( isset( $data['title'] ) && array_search( sprintf( __( '%s DESC', 'ultimate-member' ), $data['title'] ), $this->sort_fields ) !== false ) {
|
|
$data['title'] = $data['title'] . ' (' . $key . ')';
|
|
}
|
|
|
|
$title = isset( $data['title'] ) ? $data['title'] : ( isset( $data['label'] ) ? $data['label'] : '' );
|
|
if ( empty( $title ) ) {
|
|
continue;
|
|
}
|
|
|
|
// translators: %s: title.
|
|
$this->sort_fields[ $key . '_desc' ] = sprintf( __( '%s DESC', 'ultimate-member' ), $title );
|
|
// translators: %s: title.
|
|
$this->sort_fields[ $key . '_asc' ] = sprintf( __( '%s ASC', 'ultimate-member' ), $title );
|
|
}
|
|
}
|
|
}
|
|
|
|
asort( $this->sort_fields );
|
|
|
|
$this->default_sorting = apply_filters( 'um_members_directory_default_sort', array_merge( $this->sort_fields, array(
|
|
'random' => __( 'Random', 'ultimate-member' ),
|
|
'other' => __( 'Other (Custom Field)', 'ultimate-member' ),
|
|
) ) );
|
|
|
|
asort( $this->default_sorting );
|
|
|
|
// Filters
|
|
$this->filter_fields = array(
|
|
'country' => __( 'Country', 'ultimate-member' ),
|
|
'gender' => __( 'Gender', 'ultimate-member' ),
|
|
'languages' => __( 'Languages', 'ultimate-member' ),
|
|
'role' => __( 'Roles', 'ultimate-member' ),
|
|
'birth_date' => __( 'Age', 'ultimate-member' ),
|
|
'last_login' => __( 'Last Login', 'ultimate-member' ),
|
|
'user_registered' => __( 'User Registered', 'ultimate-member' ),
|
|
'first_name' => __( 'First Name', 'ultimate-member' ),
|
|
'last_name' => __( 'Last Name', 'ultimate-member' ),
|
|
'nickname' => __( 'Nickname', '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' ),
|
|
);
|
|
|
|
$this->filter_supported_fields = apply_filters( 'um_members_directory_custom_field_types_supported_filter', array( 'date', 'time', 'select', 'multiselect', 'radio', 'checkbox', 'rating', 'text', 'textarea', 'number' ) );
|
|
|
|
$core_search_keys = $this->get_core_search_fields();
|
|
|
|
$this->searching_fields = array();
|
|
if ( ! empty( UM()->builtin()->all_user_fields() ) ) {
|
|
foreach ( UM()->builtin()->all_user_fields() as $key => $data ) {
|
|
if ( in_array( $key, $core_search_keys, true ) ) {
|
|
if ( isset( $data['title'] ) && array_search( $data['title'], $this->searching_fields, true ) !== false ) {
|
|
$data['title'] = $data['title'] . ' (' . $key . ')';
|
|
}
|
|
|
|
$title = isset( $data['title'] ) ? $data['title'] : ( isset( $data['label'] ) ? $data['label'] : '' );
|
|
if ( empty( $title ) ) {
|
|
continue;
|
|
}
|
|
|
|
$this->searching_fields[ $key ] = $title;
|
|
}
|
|
}
|
|
}
|
|
if ( ! empty( UM()->builtin()->saved_fields ) ) {
|
|
foreach ( UM()->builtin()->saved_fields as $key => $data ) {
|
|
|
|
if ( '_um_last_login' === $key ) {
|
|
continue;
|
|
}
|
|
|
|
if ( isset( $data['type'] ) && in_array( $data['type'], $this->filter_supported_fields ) ) {
|
|
if ( isset( $data['title'] ) && array_search( $data['title'], $this->filter_fields ) !== false ) {
|
|
$data['title'] = $data['title'] . ' (' . $key . ')';
|
|
}
|
|
|
|
$title = isset( $data['title'] ) ? $data['title'] : ( isset( $data['label'] ) ? $data['label'] : '' );
|
|
if ( empty( $title ) ) {
|
|
continue;
|
|
}
|
|
|
|
$this->filter_fields[ $key ] = $title;
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->filter_fields = apply_filters( 'um_members_directory_filter_fields', $this->filter_fields );
|
|
|
|
ksort( $this->filter_fields );
|
|
|
|
$this->searching_fields = array_merge( $this->searching_fields, $this->filter_fields );
|
|
asort( $this->searching_fields );
|
|
|
|
$this->filter_types = apply_filters( 'um_members_directory_filter_types', array(
|
|
'country' => 'select',
|
|
'gender' => 'select',
|
|
'languages' => 'select',
|
|
'role' => 'select',
|
|
'birth_date' => 'slider',
|
|
'last_login' => 'datepicker',
|
|
'user_registered' => 'datepicker',
|
|
'first_name' => 'text',
|
|
'last_name' => 'text',
|
|
'nickname' => 'text',
|
|
'secondary_user_email' => 'text',
|
|
'description' => 'text',
|
|
'phone_number' => 'text',
|
|
'mobile_number' => 'text',
|
|
) );
|
|
|
|
$fields = UM()->builtin()->all_user_fields;
|
|
|
|
$custom_fields_types = array_flip( array_keys( $this->filter_fields ) );
|
|
foreach ( $custom_fields_types as $key => &$value ) {
|
|
if ( ! isset( $fields[ $key ] ) ) {
|
|
unset( $custom_fields_types[ $key ] );
|
|
} else {
|
|
switch ( $fields[ $key ]['type'] ) {
|
|
default:
|
|
$value = apply_filters( 'um_custom_field_filter_type', 'select', $fields[ $key ] );
|
|
break;
|
|
case 'text':
|
|
case 'textarea':
|
|
$value = 'text';
|
|
break;
|
|
case 'date':
|
|
$value = 'datepicker';
|
|
break;
|
|
case 'time':
|
|
$value = 'timepicker';
|
|
break;
|
|
case 'select':
|
|
case 'multiselect':
|
|
case 'radio':
|
|
case 'checkbox':
|
|
$value = 'select';
|
|
break;
|
|
case 'number':
|
|
case 'rating':
|
|
$value = 'slider';
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->filter_types = array_merge( $custom_fields_types, $this->filter_types );
|
|
}
|
|
|
|
|
|
/**
|
|
* Render member's directory
|
|
* filters selectboxes
|
|
*
|
|
* @param string $filter
|
|
* @param array $directory_data
|
|
* @param mixed $default_value
|
|
* @param bool $admin
|
|
*
|
|
* @return string $filter
|
|
*/
|
|
public function show_filter( $filter, $directory_data, $default_value = false, $admin = false ) {
|
|
|
|
if ( empty( $this->filter_types[ $filter ] ) ) {
|
|
return '';
|
|
}
|
|
|
|
if ( false === $default_value ) {
|
|
$default_filters = array();
|
|
if ( ! empty( $directory_data['search_filters'] ) ) {
|
|
$default_filters = maybe_unserialize( $directory_data['search_filters'] );
|
|
}
|
|
|
|
if ( ! empty( $default_filters[ $filter ] ) && 'select' !== $this->filter_types[ $filter ] ) {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
$field_key = $filter;
|
|
if ( 'last_login' === $filter ) {
|
|
$field_key = '_um_last_login';
|
|
} elseif ( 'role' === $filter ) {
|
|
$field_key = 'role_select';
|
|
}
|
|
|
|
$fields = UM()->builtin()->all_user_fields;
|
|
|
|
if ( isset( $fields[ $field_key ] ) ) {
|
|
$attrs = $fields[ $field_key ];
|
|
} else {
|
|
/**
|
|
* UM hook
|
|
*
|
|
* @type filter
|
|
* @title um_custom_search_field_{$filter}
|
|
* @description Custom search settings by $filter
|
|
* @input_vars
|
|
* [{"var":"$settings","type":"array","desc":"Search Settings"}]
|
|
* @change_log
|
|
* ["Since: 2.0"]
|
|
* @usage
|
|
* <?php add_filter( 'um_custom_search_field_{$filter}', 'function_name', 10, 1 ); ?>
|
|
* @example
|
|
* <?php
|
|
* add_filter( 'um_custom_search_field_{$filter}', 'my_custom_search_field', 10, 1 );
|
|
* function my_change_email_template_file( $settings ) {
|
|
* // your code here
|
|
* return $settings;
|
|
* }
|
|
* ?>
|
|
*/
|
|
$attrs = apply_filters( "um_custom_search_field_{$filter}", array(), $field_key );
|
|
}
|
|
|
|
// skip private invisible fields
|
|
if ( ! um_can_view_field( $attrs ) ) {
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* UM hook
|
|
*
|
|
* @type filter
|
|
* @title um_search_fields
|
|
* @description Filter all search fields
|
|
* @input_vars
|
|
* [{"var":"$settings","type":"array","desc":"Search Fields"}]
|
|
* @change_log
|
|
* ["Since: 2.0"]
|
|
* @usage
|
|
* <?php add_filter( 'um_search_fields', 'function_name', 10, 1 ); ?>
|
|
* @example
|
|
* <?php
|
|
* add_filter( 'um_search_fields', 'my_search_fields', 10, 1 );
|
|
* function my_search_fields( $settings ) {
|
|
* // your code here
|
|
* return $settings;
|
|
* }
|
|
* ?>
|
|
*/
|
|
$attrs = apply_filters( 'um_search_fields', $attrs, $field_key, $directory_data['form_id'] );
|
|
|
|
$unique_hash = substr( md5( $directory_data['form_id'] ), 10, 5 );
|
|
|
|
ob_start();
|
|
|
|
switch ( $this->filter_types[ $filter ] ) {
|
|
default:
|
|
do_action( "um_member_directory_filter_type_{$this->filter_types[ $filter ]}", $filter, $directory_data, $unique_hash, $attrs, $default_value );
|
|
break;
|
|
|
|
case 'text':
|
|
$label = '';
|
|
if ( isset( $attrs['label'] ) ) {
|
|
$label = $attrs['label'];
|
|
} elseif ( isset( $attrs['title'] ) ) {
|
|
$label = $attrs['title'];
|
|
}
|
|
|
|
$label = stripslashes( $label );
|
|
|
|
$filter_from_url = ! empty( $_GET[ 'filter_' . $filter . '_' . $unique_hash ] ) ? sanitize_text_field( $_GET[ 'filter_' . $filter . '_' . $unique_hash ] ) : $default_value;
|
|
?>
|
|
<input type="text" autocomplete="off" id="<?php echo esc_attr( $filter ); ?>" name="<?php echo esc_attr( $filter ); ?>"
|
|
placeholder="<?php echo esc_attr( $label ); ?>"
|
|
value="<?php echo esc_attr( $filter_from_url ); ?>" class="um-form-field"
|
|
aria-label="<?php echo esc_attr( $label ); ?>" />
|
|
<?php
|
|
break;
|
|
|
|
case 'select': {
|
|
|
|
// getting value from GET line
|
|
$filter_from_url = ! empty( $_GET[ 'filter_' . $filter . '_' . $unique_hash ] ) ? explode( '||', sanitize_text_field( $_GET[ 'filter_' . $filter . '_' . $unique_hash ] ) ) : array();
|
|
|
|
// new
|
|
global $wpdb;
|
|
|
|
if ( $attrs['metakey'] != 'role_select' ) {
|
|
$values_array = $wpdb->get_col(
|
|
$wpdb->prepare(
|
|
"SELECT DISTINCT meta_value
|
|
FROM $wpdb->usermeta
|
|
WHERE meta_key = %s AND
|
|
meta_value != ''",
|
|
$attrs['metakey']
|
|
)
|
|
);
|
|
} else {
|
|
$users_roles = count_users();
|
|
$values_array = ( ! empty( $users_roles['avail_roles'] ) && is_array( $users_roles['avail_roles'] ) ) ? array_keys( array_filter( $users_roles['avail_roles'] ) ) : array();
|
|
}
|
|
|
|
if ( ! empty( $values_array ) && in_array( $attrs['type'], array( 'select', 'multiselect', 'checkbox', 'radio' ), true ) ) {
|
|
$values_array = array_map( 'maybe_unserialize', $values_array );
|
|
$temp_values = array();
|
|
foreach ( $values_array as $values ) {
|
|
if ( is_array( $values ) ) {
|
|
$temp_values = array_merge( $temp_values, $values );
|
|
} else {
|
|
$temp_values[] = $values;
|
|
}
|
|
}
|
|
$values_array = array_unique( $temp_values );
|
|
}
|
|
|
|
if ( 'online_status' !== $attrs['metakey'] && empty( $values_array ) ) {
|
|
ob_get_clean();
|
|
return '';
|
|
}
|
|
|
|
if ( isset( $attrs['metakey'] ) && strstr( $attrs['metakey'], 'role_' ) ) {
|
|
$shortcode_roles = get_post_meta( $directory_data['form_id'], '_um_roles', true );
|
|
$um_roles = UM()->roles()->get_roles( false );
|
|
|
|
if ( ! empty( $shortcode_roles ) && is_array( $shortcode_roles ) ) {
|
|
$attrs['options'] = array();
|
|
|
|
foreach ( $um_roles as $key => $value ) {
|
|
if ( in_array( $key, $shortcode_roles ) ) {
|
|
$attrs['options'][ $key ] = $value;
|
|
}
|
|
}
|
|
} else {
|
|
$attrs['options'] = array();
|
|
|
|
foreach ( $um_roles as $key => $value ) {
|
|
$attrs['options'][ $key ] = $value;
|
|
}
|
|
}
|
|
}
|
|
|
|
$custom_dropdown = '';
|
|
if ( ! empty( $attrs['custom_dropdown_options_source'] ) ) {
|
|
$attrs['custom'] = true;
|
|
|
|
if ( ! empty( $attrs['parent_dropdown_relationship'] ) ) {
|
|
|
|
$custom_dropdown .= ' data-member-directory="yes"';
|
|
$custom_dropdown .= ' data-um-parent="' . esc_attr( $attrs['parent_dropdown_relationship'] ) . '"';
|
|
|
|
if ( isset( $_GET[ 'filter_' . $attrs['parent_dropdown_relationship'] . '_' . $unique_hash ] ) ) {
|
|
$_POST['parent_option_name'] = $attrs['parent_dropdown_relationship'];
|
|
|
|
$parent_option_value = sanitize_text_field( $_GET[ 'filter_' . $attrs['parent_dropdown_relationship'] . '_' . $unique_hash ] );
|
|
$_POST['parent_option'] = explode( '||', $parent_option_value );
|
|
}
|
|
}
|
|
|
|
$attrs['custom_dropdown_options_source'] = wp_unslash( $attrs['custom_dropdown_options_source'] );
|
|
|
|
$ajax_source = apply_filters( "um_custom_dropdown_options_source__{$filter}", $attrs['custom_dropdown_options_source'], $attrs );
|
|
|
|
$custom_dropdown .= ' data-um-ajax-source="' . esc_attr( $ajax_source ) . '" ';
|
|
|
|
$attrs['options'] = UM()->fields()->get_options_from_callback( $attrs, $attrs['type'] );
|
|
} else {
|
|
/** This filter is documented in includes/core/class-fields.php */
|
|
$option_pairs = apply_filters( 'um_select_options_pair', null, $attrs );
|
|
}
|
|
|
|
if ( $attrs['metakey'] != 'online_status' ) {
|
|
if ( $attrs['metakey'] != 'role_select' && $attrs['metakey'] != 'mycred_rank' && empty( $custom_dropdown ) && empty( $option_pairs ) ) {
|
|
$attrs['options'] = array_intersect( array_map( 'stripslashes', array_map( 'trim', $attrs['options'] ) ), $values_array );
|
|
} elseif ( ! empty( $custom_dropdown ) ) {
|
|
$attrs['options'] = array_intersect_key( array_map( 'trim', $attrs['options'] ), array_flip( $values_array ) );
|
|
} else {
|
|
$attrs['options'] = array_intersect_key( array_map( 'trim', $attrs['options'] ), array_flip( $values_array ) );
|
|
}
|
|
}
|
|
|
|
$attrs['options'] = apply_filters( 'um_member_directory_filter_select_options', $attrs['options'], $values_array, $attrs );
|
|
|
|
if ( ( empty( $attrs['options'] ) || ! is_array( $attrs['options'] ) ) && ! ( ! empty( $attrs['custom_dropdown_options_source'] ) && ! empty( $attrs['parent_dropdown_relationship'] ) ) ) {
|
|
ob_get_clean();
|
|
return '';
|
|
}
|
|
|
|
if ( ! empty( $attrs['custom_dropdown_options_source'] ) && ! empty( $attrs['parent_dropdown_relationship'] ) ) {
|
|
$attrs['options'] = array();
|
|
}
|
|
|
|
if ( isset( $attrs['label'] ) ) {
|
|
$attrs['label'] = strip_tags( $attrs['label'] );
|
|
}
|
|
|
|
if ( ! empty( $default_filters[ $filter ] ) ) {
|
|
$attrs['options'] = array_intersect( $attrs['options'], $default_filters[ $filter ] );
|
|
}
|
|
|
|
ksort( $attrs['options'] );
|
|
|
|
$attrs['options'] = apply_filters( 'um_member_directory_filter_select_options_sorted', $attrs['options'], $attrs );
|
|
|
|
$label = '';
|
|
if ( isset( $attrs['label'] ) ) {
|
|
$label = $attrs['label'];
|
|
} elseif ( ! isset( $attrs['label'] ) && isset( $attrs['title'] ) ) {
|
|
$label = $attrs['title'];
|
|
}
|
|
?>
|
|
|
|
<select class="um-s1" id="<?php echo esc_attr( $filter ); ?>" name="<?php echo esc_attr( $filter ); ?><?php if ( $admin && count( $attrs['options'] ) > 1 ) { ?>[]<?php } ?>"
|
|
data-placeholder="<?php esc_attr_e( stripslashes( $label ), 'ultimate-member' ); ?>"
|
|
aria-label="<?php esc_attr_e( stripslashes( $label ), 'ultimate-member' ); ?>"
|
|
<?php if ( $admin && count( $attrs['options'] ) > 1 ) { ?>multiple<?php } ?>
|
|
<?php echo $custom_dropdown; ?>>
|
|
|
|
<option></option>
|
|
|
|
<?php if ( ! empty( $attrs['options'] ) ) {
|
|
foreach ( $attrs['options'] as $k => $v ) {
|
|
|
|
$v = stripslashes( $v );
|
|
|
|
$opt = $v;
|
|
|
|
if ( strstr( $filter, 'role_' ) || $filter == 'role' ) {
|
|
$opt = $k;
|
|
}
|
|
|
|
if ( isset( $attrs['custom'] ) ) {
|
|
$opt = $k;
|
|
}
|
|
|
|
if ( ! empty( $option_pairs ) ) {
|
|
$opt = $k;
|
|
} ?>
|
|
|
|
<option value="<?php echo esc_attr( $opt ); ?>" data-value_label="<?php esc_attr_e( $v, 'ultimate-member' ); ?>"
|
|
<?php disabled( ! empty( $filter_from_url ) && in_array( $opt, $filter_from_url ) );
|
|
|
|
if ( $admin ) {
|
|
if ( ! is_array( $default_value ) ) {
|
|
$default_value = array( $default_value );
|
|
}
|
|
|
|
selected( in_array( $opt, $default_value ) );
|
|
} else {
|
|
selected( $opt === $default_value );
|
|
} ?>>
|
|
<?php _e( $v, 'ultimate-member' ); ?>
|
|
</option>
|
|
|
|
<?php }
|
|
} ?>
|
|
|
|
</select>
|
|
|
|
<?php break;
|
|
}
|
|
case 'slider': {
|
|
$range = $this->slider_filters_range( $filter, $directory_data );
|
|
if ( $range ) {
|
|
list( $single_placeholder, $plural_placeholder ) = $this->slider_range_placeholder( $filter, $attrs ); ?>
|
|
|
|
<input type="hidden" id="<?php echo $filter; ?>_min" name="<?php echo $filter; ?>[]" class="um_range_min" value="<?php echo ! empty( $default_value ) ? esc_attr( min( $default_value ) ) : '' ?>" />
|
|
<input type="hidden" id="<?php echo $filter; ?>_max" name="<?php echo $filter; ?>[]" class="um_range_max" value="<?php echo ! empty( $default_value ) ? esc_attr( max( $default_value ) ) : '' ?>" />
|
|
<div class="um-slider" data-field_name="<?php echo $filter; ?>" data-min="<?php echo esc_attr( $range[0] ); ?>" data-max="<?php echo esc_attr( $range[1] ); ?>"></div>
|
|
<div class="um-slider-range" data-placeholder-s="<?php echo esc_attr( $single_placeholder ); ?>" data-placeholder-p="<?php echo esc_attr( $plural_placeholder ); ?>" data-label="<?php echo ( ! empty( $attrs['label'] ) ) ? esc_attr__( stripslashes( $attrs['label'] ), 'ultimate-member' ) : ''; ?>"></div>
|
|
<?php }
|
|
|
|
break;
|
|
}
|
|
case 'datepicker':
|
|
$range = $this->datepicker_filters_range( $filter );
|
|
|
|
$label = ! empty( $attrs['label'] ) ? $attrs['label'] : $attrs['title'];
|
|
$label = stripslashes( $label );
|
|
|
|
$default_value_min = '';
|
|
$default_value_max = '';
|
|
if ( ! empty( $default_value[0] ) ) {
|
|
$default_value_min = $default_value[0];
|
|
}
|
|
if ( ! empty( $default_value[1] ) ) {
|
|
$default_value_max = $default_value[1];
|
|
}
|
|
|
|
if ( $range ) {
|
|
list( $min, $max ) = $range;
|
|
?>
|
|
<input type="text" id="<?php echo esc_attr( $filter ); ?>_from" name="<?php echo esc_attr( $filter ); ?>_from" class="um-datepicker-filter"
|
|
<?php // translators: %s: Datetime filter label. ?>
|
|
placeholder="<?php echo esc_attr( sprintf( __( '%s From', 'ultimate-member' ), $label ) ); ?>"
|
|
data-filter-label="<?php echo esc_attr( $label ); ?>"
|
|
data-date_min="<?php echo esc_attr( $min ); ?>" data-date_max="<?php echo esc_attr( $max ); ?>"
|
|
data-filter_name="<?php echo esc_attr( $filter ); ?>" data-range="from" data-value="<?php echo ! empty( $default_value_min ) ? esc_attr( strtotime( $default_value_min ) ) : ''; ?>" />
|
|
<input type="text" id="<?php echo esc_attr( $filter ); ?>_to" name="<?php echo esc_attr( $filter ); ?>_to" class="um-datepicker-filter"
|
|
<?php // translators: %s: Datetime filter label. ?>
|
|
placeholder="<?php echo esc_attr( sprintf( __( '%s To', 'ultimate-member' ), $label ) ); ?>"
|
|
data-filter-label="<?php echo esc_attr( $label ); ?>"
|
|
data-date_min="<?php echo esc_attr( $min ); ?>" data-date_max="<?php echo esc_attr( $max ); ?>"
|
|
data-filter_name="<?php echo esc_attr( $filter ); ?>" data-range="to" data-value="<?php echo ! empty( $default_value_max ) ? esc_attr( strtotime( $default_value_max ) ) : ''; ?>" />
|
|
<?php
|
|
}
|
|
break;
|
|
case 'timepicker':
|
|
$range = $this->timepicker_filters_range( $filter );
|
|
|
|
$label = ! empty( $attrs['label'] ) ? $attrs['label'] : $attrs['title'];
|
|
$label = stripslashes( $label );
|
|
|
|
switch ( $attrs['format'] ) {
|
|
case 'g:i a':
|
|
default:
|
|
$js_format = 'h:i a';
|
|
break;
|
|
case 'g:i A':
|
|
$js_format = 'h:i A';
|
|
break;
|
|
case 'H:i':
|
|
$js_format = 'HH:i';
|
|
break;
|
|
}
|
|
|
|
$default_value_min = '';
|
|
$default_value_max = '';
|
|
if ( ! empty( $default_value[0] ) ) {
|
|
$default_value_min = $default_value[0];
|
|
}
|
|
if ( ! empty( $default_value[1] ) ) {
|
|
$default_value_max = $default_value[1];
|
|
}
|
|
|
|
if ( $range ) {
|
|
?>
|
|
<input type="text" id="<?php echo esc_attr( $filter ); ?>_from" name="<?php echo esc_attr( $filter ); ?>_from" class="um-timepicker-filter"
|
|
<?php // translators: %s: Timepicker filter label. ?>
|
|
placeholder="<?php echo esc_attr( sprintf( __( '%s From', 'ultimate-member' ), $label ) ); ?>"
|
|
data-filter-label="<?php echo esc_attr( $label ); ?>"
|
|
data-min="<?php echo esc_attr( $range[0] ); ?>" data-max="<?php echo esc_attr( $range[1] ); ?>"
|
|
data-format="<?php echo esc_attr( $js_format ); ?>" data-intervals="<?php echo esc_attr( $attrs['intervals'] ); ?>"
|
|
data-filter_name="<?php echo esc_attr( $filter ); ?>" data-range="from" data-value="<?php echo ! empty( $default_value_min ) ? esc_attr( $default_value_min ) : ''; ?>" />
|
|
<input type="text" id="<?php echo esc_attr( $filter ); ?>_to" name="<?php echo esc_attr( $filter ); ?>_to" class="um-timepicker-filter"
|
|
<?php // translators: %s: Timepicker filter label. ?>
|
|
placeholder="<?php echo esc_attr( sprintf( __( '%s To', 'ultimate-member' ), $label ) ); ?>"
|
|
data-filter-label="<?php echo esc_attr( $label ); ?>"
|
|
data-min="<?php echo esc_attr( $range[0] ); ?>" data-max="<?php echo esc_attr( $range[1] ); ?>"
|
|
data-format="<?php echo esc_attr( $js_format ); ?>" data-intervals="<?php echo esc_attr( $attrs['intervals'] ); ?>"
|
|
data-filter_name="<?php echo esc_attr( $filter ); ?>" data-range="to" data-value="<?php echo ! empty( $default_value_max ) ? esc_attr( $default_value_max ) : ''; ?>" />
|
|
<?php
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
$filter = ob_get_clean();
|
|
return $filter;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $filter
|
|
* @param array $directory_data
|
|
*
|
|
* @return mixed
|
|
*/
|
|
function slider_filters_range( $filter, $directory_data ) {
|
|
global $wpdb;
|
|
|
|
$range = false;
|
|
|
|
switch ( $filter ) {
|
|
|
|
default: {
|
|
|
|
$meta = $wpdb->get_row(
|
|
$wpdb->prepare(
|
|
"SELECT MIN( CONVERT( meta_value, DECIMAL ) ) as min_meta,
|
|
MAX( CONVERT( meta_value, DECIMAL ) ) as max_meta,
|
|
COUNT( DISTINCT meta_value ) as amount
|
|
FROM {$wpdb->usermeta}
|
|
WHERE meta_key = %s",
|
|
$filter
|
|
),
|
|
ARRAY_A
|
|
);
|
|
|
|
if ( isset( $meta['min_meta'] ) && isset( $meta['max_meta'] ) && isset( $meta['amount'] ) && $meta['amount'] > 1 ) {
|
|
$range = array( (float) $meta['min_meta'], (float) $meta['max_meta'] );
|
|
}
|
|
|
|
$range = apply_filters( 'um_member_directory_filter_slider_common', $range, $directory_data, $filter );
|
|
$range = apply_filters( "um_member_directory_filter_{$filter}_slider", $range, $directory_data );
|
|
|
|
break;
|
|
}
|
|
case 'birth_date': {
|
|
$meta = $wpdb->get_row(
|
|
"SELECT MIN( meta_value ) as min_meta,
|
|
MAX( meta_value ) as max_meta,
|
|
COUNT( DISTINCT meta_value ) as amount
|
|
FROM {$wpdb->usermeta}
|
|
WHERE meta_key = 'birth_date' AND
|
|
meta_value != ''",
|
|
ARRAY_A
|
|
);
|
|
|
|
if ( isset( $meta['min_meta'] ) && isset( $meta['max_meta'] ) && isset( $meta['amount'] ) && $meta['amount'] > 1 ) {
|
|
$range = array( $this->borndate( strtotime( $meta['max_meta'] ) ), $this->borndate( strtotime( $meta['min_meta'] ) ) );
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return $range;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $filter
|
|
*
|
|
* @return mixed
|
|
*/
|
|
function slider_range_placeholder( $filter, $attrs ) {
|
|
switch ( $filter ) {
|
|
default: {
|
|
$label = ! empty( $attrs['label'] ) ? $attrs['label'] : $filter;
|
|
$label = ucwords( str_replace( array( 'um_', '_' ), array( '', ' ' ), $label ) );
|
|
$placeholders = apply_filters( 'um_member_directory_filter_slider_range_placeholder', false, $filter );
|
|
|
|
if ( ! $placeholders ) {
|
|
switch ( $attrs['type'] ) {
|
|
default:
|
|
$placeholders = array(
|
|
"<strong>$label:</strong> {value}",
|
|
"<strong>$label:</strong> {min_range} - {max_range}",
|
|
);
|
|
break;
|
|
case 'rating':
|
|
$placeholders = array(
|
|
"<strong>$label:</strong> {value}" . __( ' stars', 'ultimate-member' ),
|
|
"<strong>$label:</strong> {min_range} - {max_range}" . __( ' stars', 'ultimate-member' )
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case 'birth_date': {
|
|
$placeholders = array(
|
|
__( '<strong>Age:</strong> {value} years old', 'ultimate-member' ),
|
|
__( '<strong>Age:</strong> {min_range} - {max_range} years old', 'ultimate-member' )
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $placeholders;
|
|
}
|
|
|
|
/**
|
|
* @param $filter
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function datepicker_filters_range( $filter ) {
|
|
global $wpdb;
|
|
|
|
switch ( $filter ) {
|
|
default:
|
|
global $wpdb;
|
|
$meta = $wpdb->get_col(
|
|
$wpdb->prepare(
|
|
"SELECT DISTINCT meta_value
|
|
FROM {$wpdb->usermeta}
|
|
WHERE meta_key = %s
|
|
ORDER BY meta_value DESC",
|
|
$filter
|
|
)
|
|
);
|
|
|
|
if ( empty( $meta ) || count( $meta ) === 1 ) {
|
|
$range = false;
|
|
} elseif ( ! empty( $meta ) ) {
|
|
$range = array( strtotime( min( $meta ) ), strtotime( max( $meta ) ) );
|
|
}
|
|
|
|
$range = apply_filters( "um_member_directory_filter_{$filter}_datepicker", $range );
|
|
|
|
break;
|
|
case 'last_login':
|
|
$meta = $wpdb->get_row(
|
|
"SELECT DISTINCT COUNT(*) AS total,
|
|
MIN(meta_value) AS min,
|
|
MAX(meta_value) AS max
|
|
FROM {$wpdb->usermeta}
|
|
WHERE meta_key = '_um_last_login'",
|
|
ARRAY_A
|
|
);
|
|
if ( empty( $meta['total'] ) || 1 === absint( $meta['total'] ) ) {
|
|
$range = false;
|
|
} elseif ( array_key_exists( 'min', $meta ) && array_key_exists( 'max', $meta ) ) {
|
|
$range = array( strtotime( $meta['min'] ), strtotime( $meta['max'] ) );
|
|
}
|
|
break;
|
|
case 'user_registered':
|
|
$meta = $wpdb->get_col(
|
|
"SELECT DISTINCT user_registered
|
|
FROM {$wpdb->users}
|
|
ORDER BY user_registered DESC"
|
|
);
|
|
|
|
if ( empty( $meta ) || count( $meta ) === 1 ) {
|
|
$range = false;
|
|
} elseif ( ! empty( $meta ) ) {
|
|
$range = array( strtotime( min( $meta ) ), strtotime( max( $meta ) ) );
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return $range;
|
|
}
|
|
|
|
/**
|
|
* @param $filter
|
|
*
|
|
* @return mixed
|
|
*/
|
|
protected function timepicker_filters_range( $filter ) {
|
|
global $wpdb;
|
|
$meta = $wpdb->get_col(
|
|
$wpdb->prepare(
|
|
"SELECT DISTINCT meta_value
|
|
FROM {$wpdb->usermeta}
|
|
WHERE meta_key = %s
|
|
ORDER BY meta_value DESC",
|
|
$filter
|
|
)
|
|
);
|
|
|
|
$meta = array_filter( $meta );
|
|
|
|
if ( empty( $meta ) || count( $meta ) === 1 ) {
|
|
$range = false;
|
|
} elseif ( ! empty( $meta ) ) {
|
|
$range = array( min( $meta ), max( $meta ) );
|
|
}
|
|
|
|
return apply_filters( "um_member_directory_filter_{$filter}_timepicker", $range );
|
|
}
|
|
|
|
/**
|
|
* @param $borndate
|
|
*
|
|
* @return false|string
|
|
*/
|
|
function borndate( $borndate ) {
|
|
if ( date('m', $borndate) > date('m') || date('m', $borndate) == date('m') && date('d', $borndate ) > date('d')) {
|
|
return (date('Y') - date('Y', $borndate ) - 1);
|
|
}
|
|
return (date('Y') - date('Y', $borndate));
|
|
}
|
|
|
|
|
|
/**
|
|
* Handle members can view restrictions
|
|
*/
|
|
function restriction_options() {
|
|
$this->hide_not_approved();
|
|
$this->hide_by_role();
|
|
$this->hide_by_account_settings();
|
|
|
|
do_action( 'um_member_directory_restrictions_handle_extend' );
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
*/
|
|
function hide_not_approved() {
|
|
if ( UM()->roles()->um_user_can( 'can_edit_everyone' ) ) {
|
|
return;
|
|
}
|
|
|
|
$this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( array(
|
|
'key' => 'um_member_directory_data',
|
|
'value' => 's:14:"account_status";s:8:"approved";',
|
|
'compare' => 'LIKE'
|
|
) ) );
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
*/
|
|
function hide_by_role() {
|
|
if ( ! is_user_logged_in() ) {
|
|
return;
|
|
}
|
|
|
|
$roles = um_user( 'can_view_roles' );
|
|
$roles = maybe_unserialize( $roles );
|
|
|
|
if ( UM()->roles()->um_user_can( 'can_view_all' ) && empty( $roles ) ) {
|
|
return;
|
|
}
|
|
|
|
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'] );
|
|
$this->query_args['role__in'] = array_intersect( $this->query_args['role__in'], $roles );
|
|
} else {
|
|
$this->query_args['role__in'] = $roles;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
*/
|
|
function hide_by_account_settings() {
|
|
if ( ! UM()->options()->get( 'account_hide_in_directory' ) ) {
|
|
return;
|
|
}
|
|
|
|
if ( UM()->roles()->um_user_can( 'can_edit_everyone' ) ) {
|
|
return;
|
|
}
|
|
|
|
$this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( array(
|
|
'key' => 'um_member_directory_data',
|
|
'value' => 's:15:"hide_in_members";b:0;',
|
|
'compare' => 'LIKE'
|
|
) ) );
|
|
}
|
|
|
|
|
|
/**
|
|
* Handle "General Options" metabox settings
|
|
*
|
|
* @param array $directory_data
|
|
*/
|
|
function general_options( $directory_data ) {
|
|
$this->show_selected_roles( $directory_data );
|
|
$this->show_only_with_avatar( $directory_data );
|
|
$this->show_only_with_cover( $directory_data );
|
|
$this->show_only_these_users( $directory_data );
|
|
$this->exclude_these_users( $directory_data );
|
|
|
|
do_action( 'um_member_directory_general_options_handle_extend', $directory_data );
|
|
}
|
|
|
|
|
|
/**
|
|
* Handle "User Roles to Display" option
|
|
*
|
|
* @param array $directory_data
|
|
*/
|
|
function show_selected_roles( $directory_data ) {
|
|
// add roles to appear in directory
|
|
if ( ! empty( $directory_data['roles'] ) ) {
|
|
//since WP4.4 use 'role__in' argument
|
|
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'] );
|
|
$this->query_args['role__in'] = array_intersect( $this->query_args['role__in'], maybe_unserialize( $directory_data['roles'] ) );
|
|
} else {
|
|
$this->query_args['role__in'] = maybe_unserialize( $directory_data['roles'] );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Handle "Only show members who have uploaded a profile photo" option
|
|
*
|
|
* @param array $directory_data
|
|
*/
|
|
function show_only_with_avatar( $directory_data ) {
|
|
if ( $directory_data['has_profile_photo'] == 1 ) {
|
|
$this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( array(
|
|
'key' => 'um_member_directory_data',
|
|
'value' => 's:13:"profile_photo";b:1;',
|
|
'compare' => 'LIKE'
|
|
) ) );
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Handle "Only show members who have uploaded a cover photo" option
|
|
*
|
|
* @param array $directory_data
|
|
*/
|
|
function show_only_with_cover( $directory_data ) {
|
|
if ( $directory_data['has_cover_photo'] == 1 ) {
|
|
$this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( array(
|
|
'key' => 'um_member_directory_data',
|
|
'value' => 's:11:"cover_photo";b:1;',
|
|
'compare' => 'LIKE'
|
|
) ) );
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Handle "Only show specific users (Enter one username per line)" option
|
|
*
|
|
* @param array $directory_data
|
|
*/
|
|
function show_only_these_users( $directory_data ) {
|
|
if ( ! empty( $directory_data['show_these_users'] ) ) {
|
|
$show_these_users = maybe_unserialize( $directory_data['show_these_users'] );
|
|
|
|
if ( is_array( $show_these_users ) && ! empty( $show_these_users ) ) {
|
|
|
|
$users_array = array();
|
|
|
|
foreach ( $show_these_users as $username ) {
|
|
if ( false !== ( $exists_id = username_exists( $username ) ) ) {
|
|
$users_array[] = $exists_id;
|
|
}
|
|
}
|
|
|
|
if ( ! empty( $users_array ) ) {
|
|
$this->query_args['include'] = $users_array;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Handle "Exclude specific users (Enter one username per line)" option
|
|
*
|
|
* @param array $directory_data
|
|
*/
|
|
function exclude_these_users( $directory_data ) {
|
|
if ( ! empty( $directory_data['exclude_these_users'] ) ) {
|
|
$exclude_these_users = maybe_unserialize( $directory_data['exclude_these_users'] );
|
|
|
|
if ( is_array( $exclude_these_users ) && ! empty( $exclude_these_users ) ) {
|
|
|
|
$users_array = array();
|
|
|
|
foreach ( $exclude_these_users as $username ) {
|
|
if ( false !== ( $exists_id = username_exists( $username ) ) ) {
|
|
$users_array[] = $exists_id;
|
|
}
|
|
}
|
|
|
|
if ( ! empty( $users_array ) ) {
|
|
$this->query_args['exclude'] = $users_array;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Handle "Pagination Options" metabox settings
|
|
*
|
|
* @param array $directory_data
|
|
*/
|
|
function pagination_options( $directory_data ) {
|
|
// number of profiles for mobile
|
|
$profiles_per_page = $directory_data['profiles_per_page'];
|
|
if ( wp_is_mobile() && isset( $directory_data['profiles_per_page_mobile'] ) ) {
|
|
$profiles_per_page = $directory_data['profiles_per_page_mobile'];
|
|
}
|
|
|
|
$this->query_args['number'] = ( ! empty( $directory_data['max_users'] ) && $directory_data['max_users'] <= $profiles_per_page ) ? $directory_data['max_users'] : $profiles_per_page;
|
|
$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
|
|
*/
|
|
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 = ( '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 );
|
|
$custom_sort[] = $field_keys[0];
|
|
}
|
|
}
|
|
}
|
|
|
|
$numeric_sorting_keys = array();
|
|
|
|
if ( ! empty( UM()->builtin()->saved_fields ) ) {
|
|
foreach ( UM()->builtin()->saved_fields as $key => $data ) {
|
|
if ( '_um_last_login' === $key ) {
|
|
continue;
|
|
}
|
|
|
|
if ( isset( $data['type'] ) && 'number' === $data['type'] ) {
|
|
if ( array_key_exists( $key . '_desc', $this->sort_fields ) ) {
|
|
$numeric_sorting_keys[] = $key . '_desc';
|
|
}
|
|
if ( array_key_exists( $key . '_asc', $this->sort_fields ) ) {
|
|
$numeric_sorting_keys[] = $key . '_asc';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( 'username' == $sortby ) {
|
|
|
|
$this->query_args['orderby'] = 'user_login';
|
|
$this->query_args['order'] = 'ASC';
|
|
|
|
} elseif ( 'display_name' == $sortby ) {
|
|
|
|
$display_name = UM()->options()->get( 'display_name' );
|
|
if ( $display_name == 'username' ) {
|
|
$this->query_args['orderby'] = 'user_login';
|
|
$this->query_args['order'] = 'ASC';
|
|
} else {
|
|
$this->query_args['meta_query'][] = array(
|
|
'relation' => 'OR',
|
|
'full_name' => array(
|
|
'key' => 'full_name',
|
|
'compare' => 'EXISTS'
|
|
),
|
|
array(
|
|
'key' => 'full_name',
|
|
'compare' => 'NOT EXISTS'
|
|
)
|
|
);
|
|
|
|
$this->query_args['orderby'] = 'full_name, display_name';
|
|
$this->query_args['order'] = 'ASC';
|
|
}
|
|
|
|
} 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,
|
|
'compare' => 'EXISTS',
|
|
), ) );
|
|
|
|
$this->query_args['orderby'] = array( $sortby . '_c' => 'ASC' );
|
|
unset( $this->query_args['order'] );
|
|
|
|
} elseif ( 'last_login' === $sortby ) {
|
|
$this->query_args['orderby'] = array( 'um_last_login' => 'DESC' );
|
|
// Please use custom meta table for better results and sorting. Here we only hide the users without visible last login date.
|
|
$this->query_args['meta_query'][] = array(
|
|
'relation' => 'OR',
|
|
array(
|
|
'key' => '_um_last_login',
|
|
'compare' => 'EXISTS',
|
|
'type' => 'DATETIME',
|
|
),
|
|
'um_last_login' => array(
|
|
'key' => '_um_last_login',
|
|
'compare' => 'NOT EXISTS',
|
|
'type' => 'DATETIME',
|
|
),
|
|
);
|
|
unset( $this->query_args['order'] );
|
|
|
|
add_filter( 'pre_user_query', array( &$this, 'sortby_last_login' ) );
|
|
} elseif ( $sortby == 'last_first_name' ) {
|
|
|
|
$this->query_args['meta_query'][] = array(
|
|
'last_name_c' => array(
|
|
'key' => 'last_name',
|
|
'compare' => 'EXISTS',
|
|
),
|
|
'first_name_c' => array(
|
|
'key' => 'first_name',
|
|
'compare' => 'EXISTS',
|
|
),
|
|
);
|
|
|
|
$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, true ) ) {
|
|
|
|
$order = 'DESC';
|
|
if ( strstr( $sortby, '_desc' ) ) {
|
|
$sortby = str_replace( '_desc', '', $sortby );
|
|
$order = 'DESC';
|
|
}
|
|
|
|
if ( strstr( $sortby, '_asc' ) ) {
|
|
$sortby = str_replace( '_asc', '', $sortby );
|
|
$order = 'ASC';
|
|
}
|
|
|
|
$this->query_args['meta_query'] = array_merge(
|
|
$this->query_args['meta_query'],
|
|
array(
|
|
array(
|
|
'relation' => 'OR',
|
|
array(
|
|
'key' => $sortby,
|
|
'compare' => 'EXISTS',
|
|
'type' => 'NUMERIC',
|
|
),
|
|
$sortby . '_ns' => array(
|
|
'key' => $sortby,
|
|
'compare' => 'NOT EXISTS',
|
|
'type' => 'NUMERIC',
|
|
),
|
|
),
|
|
)
|
|
);
|
|
|
|
$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, 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_unserialize( $directory_data['sorting_fields'] );
|
|
|
|
if ( ! empty( $sorting_fields ) && is_array( $sorting_fields ) ) {
|
|
foreach ( $sorting_fields as $field ) {
|
|
if ( isset( $field[ $sorting ] ) ) {
|
|
$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 <caption>Change type to DATE by the directory ID and mete_key.</caption>
|
|
* 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(
|
|
'relation' => 'OR',
|
|
$sortby . '_cs' => array(
|
|
'key' => $sortby,
|
|
'compare' => 'EXISTS',
|
|
'type' => $custom_sort_type,
|
|
),
|
|
array(
|
|
'key' => $sortby,
|
|
'compare' => 'NOT EXISTS',
|
|
),
|
|
);
|
|
|
|
$this->query_args['orderby'] = array(
|
|
$sortby . '_cs' => $custom_sort_order,
|
|
'user_login' => 'ASC',
|
|
);
|
|
|
|
} else {
|
|
|
|
if ( strstr( $sortby, '_desc' ) ) {
|
|
$sortby = str_replace( '_desc', '', $sortby );
|
|
$order = 'DESC';
|
|
}
|
|
|
|
if ( strstr( $sortby, '_asc' ) ) {
|
|
$sortby = str_replace( '_asc', '', $sortby );
|
|
$order = 'ASC';
|
|
}
|
|
|
|
$this->query_args['orderby'] = $sortby;
|
|
if ( isset( $order ) ) {
|
|
$this->query_args['order'] = $order;
|
|
}
|
|
|
|
add_filter( 'pre_user_query', array( &$this, 'sortby_randomly' ), 10, 1 );
|
|
}
|
|
|
|
/**
|
|
* UM hook
|
|
*
|
|
* @type filter
|
|
* @title um_modify_sortby_parameter
|
|
* @description Change query sort by attributes for search at Members Directory
|
|
* @input_vars
|
|
* [{"var":"$query_args","type":"array","desc":"Query Arguments"},
|
|
* {"var":"$sortby","type":"string","desc":"Sort by"}]
|
|
* @change_log
|
|
* ["Since: 2.0"]
|
|
* @usage
|
|
* <?php add_filter( 'um_modify_sortby_parameter', 'function_name', 10, 2 ); ?>
|
|
* @example
|
|
* <?php
|
|
* add_filter( 'um_modify_sortby_parameter', 'my_modify_sortby_parameter', 10, 2 );
|
|
* function my_modify_sortby_parameter( $query_args, $sortby ) {
|
|
* // your code here
|
|
* return $query_args;
|
|
* }
|
|
* ?>
|
|
*/
|
|
$this->query_args = apply_filters( 'um_modify_sortby_parameter', $this->query_args, $sortby );
|
|
}
|
|
|
|
|
|
/**
|
|
* Sorting random
|
|
*
|
|
* @param object $query
|
|
*
|
|
* @return mixed
|
|
*/
|
|
function sortby_randomly( $query ) {
|
|
if ( 'random' == $query->query_vars['orderby'] ) {
|
|
|
|
if ( um_is_session_started() === false ) {
|
|
@session_start();
|
|
}
|
|
|
|
// Reset seed on load of initial
|
|
if ( empty( $_REQUEST['directory_id'] ) && isset( $_SESSION['um_member_directory_seed'] ) ) {
|
|
unset( $_SESSION['um_member_directory_seed'] );
|
|
}
|
|
|
|
// Get seed from session variable if it exists
|
|
$seed = false;
|
|
if ( isset( $_SESSION['um_member_directory_seed'] ) ) {
|
|
$seed = $_SESSION['um_member_directory_seed'];
|
|
}
|
|
|
|
// Set new seed if none exists
|
|
if ( ! $seed ) {
|
|
$seed = rand();
|
|
$_SESSION['um_member_directory_seed'] = $seed;
|
|
}
|
|
|
|
$query->query_orderby = 'ORDER by RAND(' . $seed . ')';
|
|
}
|
|
|
|
return $query;
|
|
}
|
|
|
|
|
|
/**
|
|
* Sorting by last login
|
|
*
|
|
* @param object $query
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function sortby_last_login( $query ) {
|
|
if ( array_key_exists( 'um_last_login', $query->query_vars['orderby'] ) ) {
|
|
global $wpdb;
|
|
$query->query_from .= " LEFT JOIN {$wpdb->prefix}usermeta AS umm_sort ON ( umm_sort.user_id = {$wpdb->prefix}users.ID AND umm_sort.meta_key = '_um_last_login' ) ";
|
|
$query->query_from .= " LEFT JOIN {$wpdb->prefix}usermeta AS umm_show_login ON ( umm_show_login.user_id = {$wpdb->prefix}users.ID AND umm_show_login.meta_key = 'um_show_last_login' ) ";
|
|
$query->query_orderby = " ORDER BY CASE ISNULL(NULLIF(umm_show_login.meta_value,'a:1:{i:0;s:3:\"yes\";}')) WHEN 0 THEN '1970-01-01 00:00:00' ELSE CAST( umm_sort.meta_value AS DATETIME ) END DESC ";
|
|
}
|
|
return $query;
|
|
}
|
|
|
|
/**
|
|
* Prepare the search line. Avoid the using mySQL statement.
|
|
*
|
|
* @param string $search
|
|
*
|
|
* @return string
|
|
*/
|
|
protected function prepare_search( $search ) {
|
|
// unslash, sanitize, trim - necessary prepare.
|
|
$search = trim( sanitize_text_field( wp_unslash( $search ) ) );
|
|
if ( empty( $search ) ) {
|
|
return '';
|
|
}
|
|
|
|
// Make the search line empty if it contains the mySQL query statements.
|
|
$regexp_map = array(
|
|
'/select(.*?)from/im',
|
|
'/select(.*?)sleep/im',
|
|
"/sleep\(\s*[\"'`]?\s*\d+\s*[\"'`]?\s*\)/im", // avoid any sleep injections
|
|
"/benchmark\(\s*[\"'`]?\s*\d+\s*[\"'`]?\s*,.*\)/im", // avoid any benchmark injections
|
|
'/select(.*?)database/im',
|
|
'/select(.*?)where/im',
|
|
'/update(.*?)set/im',
|
|
'/delete(.*?)from/im',
|
|
);
|
|
|
|
foreach ( $regexp_map as $regexp ) {
|
|
preg_match( $regexp, $search, $matches );
|
|
if ( ! empty( $matches ) ) {
|
|
$search = '';
|
|
break;
|
|
}
|
|
}
|
|
// Early escape of the search line. The same as `$wpdb->prepare()`.
|
|
return esc_sql( $search );
|
|
}
|
|
|
|
/**
|
|
* Handle general search line request
|
|
*/
|
|
public function general_search() {
|
|
// General search
|
|
if ( ! empty( $_POST['search'] ) ) {
|
|
// complex using with change_meta_sql function
|
|
$search = $this->prepare_search( $_POST['search'] );
|
|
if ( ! empty( $search ) ) {
|
|
$meta_query = array(
|
|
'relation' => 'OR',
|
|
array(
|
|
'value' => $search,
|
|
'compare' => '=',
|
|
),
|
|
array(
|
|
'value' => $search,
|
|
'compare' => 'LIKE',
|
|
),
|
|
array(
|
|
'value' => serialize( (string) $search ),
|
|
'compare' => 'LIKE',
|
|
),
|
|
);
|
|
|
|
$meta_query = apply_filters( 'um_member_directory_general_search_meta_query', $meta_query, $search );
|
|
|
|
$this->query_args['meta_query'][] = $meta_query;
|
|
|
|
$this->is_search = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Change mySQL meta query join attribute
|
|
* for search only by UM user meta fields and WP core fields in WP Users table
|
|
*
|
|
* @param array $sql Array containing the query's JOIN and WHERE clauses.
|
|
* @param $queries
|
|
* @param $type
|
|
* @param $primary_table
|
|
* @param $primary_id_column
|
|
* @param WP_User_Query $context
|
|
*
|
|
* @return array
|
|
*/
|
|
public function change_meta_sql( $sql, $queries, $type, $primary_table, $primary_id_column, $context ) {
|
|
if ( ! empty( $_POST['search'] ) ) {
|
|
$search = $this->prepare_search( $_POST['search'] );
|
|
if ( ! empty( $search ) ) {
|
|
global $wpdb;
|
|
|
|
$meta_value = '%' . $wpdb->esc_like( $search ) . '%';
|
|
$search_meta = $wpdb->prepare( '%s', $meta_value );
|
|
|
|
preg_match( '~(?<=\{)(.*?)(?=\})~', $search_meta, $matches, PREG_OFFSET_CAPTURE, 0 );
|
|
|
|
// workaround for standard mySQL hashes which are used by $wpdb->prepare instead of the %symbol
|
|
// sometimes it breaks error for strings like that wp_postmeta.meta_value LIKE '{12f209b48a89eeab33424902879d05d503f251ca8812dde03b59484a2991dc74}AMS{12f209b48a89eeab33424902879d05d503f251ca8812dde03b59484a2991dc74}'
|
|
// {12f209b48a89eeab33424902879d05d503f251ca8812dde03b59484a2991dc74} isn't applied by the `preg_replace()` below
|
|
if ( $matches[0][0] ) {
|
|
$search_meta = str_replace( '{' . $matches[0][0] . '}', '#%&', $search_meta );
|
|
$sql['where'] = str_replace( '{' . $matches[0][0] . '}', '#%&', $sql['where'] );
|
|
}
|
|
|
|
// str_replace( '/', '\/', wp_slash( $search_meta ) ) means that we add backslashes to special symbols + add backslash to slash(/) symbol for proper regular pattern.
|
|
preg_match(
|
|
'/^(.*).meta_value LIKE ' . str_replace( '/', '\/', wp_slash( $search_meta ) ) . '[^\)]/im',
|
|
$sql['where'],
|
|
$join_matches
|
|
);
|
|
|
|
$sql['where'] = str_replace( '#%&', '{' . $matches[0][0] . '}', $sql['where'] );
|
|
|
|
$directory_id = $this->get_directory_by_hash( sanitize_key( $_POST['directory_id'] ) );
|
|
$exclude_fields = get_post_meta( $directory_id, '_um_search_exclude_fields', true );
|
|
$include_fields = get_post_meta( $directory_id, '_um_search_include_fields', true );
|
|
|
|
if ( isset( $join_matches[1] ) ) {
|
|
$meta_join_for_search = trim( $join_matches[1] );
|
|
|
|
// skip private invisible fields
|
|
$custom_fields = array();
|
|
if ( empty( $include_fields ) ) {
|
|
foreach ( array_keys( UM()->builtin()->all_user_fields ) as $field_key ) {
|
|
if ( empty( $field_key ) ) {
|
|
continue;
|
|
}
|
|
|
|
$data = UM()->fields()->get_field( $field_key );
|
|
if ( ! um_can_view_field( $data ) ) {
|
|
continue;
|
|
}
|
|
|
|
$custom_fields[] = $field_key;
|
|
}
|
|
} else {
|
|
foreach ( $include_fields as $field_key ) {
|
|
if ( empty( $field_key ) ) {
|
|
continue;
|
|
}
|
|
|
|
$data = UM()->fields()->get_field( $field_key );
|
|
if ( ! um_can_view_field( $data ) ) {
|
|
continue;
|
|
}
|
|
|
|
$custom_fields[] = $field_key;
|
|
}
|
|
}
|
|
|
|
$custom_fields = apply_filters( 'um_general_search_custom_fields', $custom_fields );
|
|
|
|
if ( ! empty( $custom_fields ) ) {
|
|
if ( ! empty( $exclude_fields ) ) {
|
|
$custom_fields = array_diff( $custom_fields, $exclude_fields );
|
|
}
|
|
|
|
$sql['join'] = preg_replace(
|
|
'/(' . $meta_join_for_search . ' ON \( ' . $wpdb->users . '\.ID = ' . $meta_join_for_search . '\.user_id )(\))/im',
|
|
"$1 AND " . $meta_join_for_search . ".meta_key IN( '" . implode( "','", $custom_fields ) . "' ) $2",
|
|
$sql['join']
|
|
);
|
|
}
|
|
}
|
|
|
|
$core_search = $this->get_core_search_fields();
|
|
if ( ! empty( $include_fields ) ) {
|
|
$core_search = array_intersect( $core_search, $include_fields );
|
|
}
|
|
if ( ! empty( $exclude_fields ) ) {
|
|
$core_search = array_diff( $core_search, $exclude_fields );
|
|
}
|
|
|
|
if ( ! empty( $core_search ) ) {
|
|
// Add OR instead AND to search in WP core fields user_email, user_login, user_display_name
|
|
$search_where = $context->get_search_sql( $search, $core_search, 'both' );
|
|
|
|
$search_where = preg_replace( '/ AND \((.*?)\)/im', "$1 OR", $search_where );
|
|
|
|
// str_replace( '/', '\/', wp_slash( $search ) ) means that we add backslashes to special symbols + add backslash to slash(/) symbol for proper regular pattern.
|
|
$pattern = $wpdb->prepare( $meta_join_for_search . '.meta_value = %s', $search );
|
|
$pattern = '/(' . str_replace( '/', '\/', wp_slash( $pattern ) ) . ')/im';
|
|
|
|
$sql['where'] = preg_replace(
|
|
$pattern,
|
|
trim( $search_where ) . " $1",
|
|
$sql['where'],
|
|
1
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $sql;
|
|
}
|
|
|
|
/**
|
|
* Handle filters request
|
|
*/
|
|
function filters( $directory_data ) {
|
|
global $wpdb;
|
|
//filters
|
|
$filter_query = array();
|
|
if ( ! empty( $directory_data['search_fields'] ) ) {
|
|
$search_filters = maybe_unserialize( $directory_data['search_fields'] );
|
|
|
|
if ( ! empty( $search_filters ) && is_array( $search_filters ) ) {
|
|
$filter_query = array_intersect_key( $_POST, array_flip( $search_filters ) );
|
|
}
|
|
}
|
|
|
|
// added for user tags extension integration on individual tag page
|
|
$ignore_empty_filters = apply_filters( 'um_member_directory_ignore_empty_filters', false );
|
|
|
|
if ( empty( $filter_query ) && ! $ignore_empty_filters ) {
|
|
return;
|
|
}
|
|
|
|
$this->is_search = true;
|
|
foreach ( $filter_query as $field => $value ) {
|
|
$field = sanitize_text_field( $field );
|
|
if ( is_array( $value ) ) {
|
|
$value = array_map( 'sanitize_text_field', $value );
|
|
} else {
|
|
$value = sanitize_text_field( $value );
|
|
}
|
|
|
|
$attrs = UM()->fields()->get_field( $field );
|
|
// skip private invisible fields
|
|
if ( ! um_can_view_field( $attrs ) ) {
|
|
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 ];
|
|
|
|
/**
|
|
* 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 );
|
|
|
|
$field_query = apply_filters( 'um_query_args_filter_global', $field_query, $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':
|
|
|
|
$value = stripslashes( $value );
|
|
$field_query = array(
|
|
'relation' => 'OR',
|
|
array(
|
|
'key' => $field,
|
|
'value' => trim( $value ),
|
|
'compare' => apply_filters( 'um_members_directory_filter_text', 'LIKE', $field )
|
|
),
|
|
);
|
|
|
|
$this->custom_filters_in_query[ $field ] = $value;
|
|
|
|
break;
|
|
|
|
case 'select':
|
|
if ( is_array( $value ) ) {
|
|
$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' => '=',
|
|
),
|
|
array(
|
|
'key' => $field,
|
|
'value' => serialize( (string) $single_val ),
|
|
'compare' => 'LIKE',
|
|
),
|
|
array(
|
|
'key' => $field,
|
|
'value' => '"' . $single_val . '"',
|
|
'compare' => 'LIKE',
|
|
),
|
|
);
|
|
|
|
if ( is_numeric( $single_val ) ) {
|
|
|
|
$arr_meta_query[] = array(
|
|
'key' => $field,
|
|
'value' => serialize( absint( $single_val ) ),
|
|
'compare' => 'LIKE',
|
|
);
|
|
|
|
}
|
|
|
|
$field_query = array_merge( $field_query, $arr_meta_query );
|
|
}
|
|
}
|
|
|
|
$this->custom_filters_in_query[ $field ] = $value;
|
|
|
|
break;
|
|
case 'slider':
|
|
|
|
$this->custom_filters_in_query[ $field ] = $value;
|
|
|
|
$field_query = array(
|
|
'key' => $field,
|
|
'value' => $value,
|
|
'compare' => 'BETWEEN',
|
|
'inclusive' => true,
|
|
'type' => 'NUMERIC',
|
|
);
|
|
|
|
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 );
|
|
|
|
$field_query = array(
|
|
'key' => $field,
|
|
'value' => array( $from_date, $to_date ),
|
|
'compare' => 'BETWEEN',
|
|
'inclusive' => true,
|
|
);
|
|
|
|
$this->custom_filters_in_query[ $field ] = array( $from_date, $to_date );
|
|
|
|
break;
|
|
case 'timepicker':
|
|
|
|
if ( $value[0] == $value[1] ) {
|
|
$field_query = array(
|
|
'key' => $field,
|
|
'value' => $value[0],
|
|
);
|
|
} else {
|
|
$field_query = array(
|
|
'key' => $field,
|
|
'value' => $value,
|
|
'compare' => 'BETWEEN',
|
|
'type' => 'TIME',
|
|
'inclusive' => true,
|
|
);
|
|
}
|
|
|
|
$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 ( '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['meta_query'] = array_merge( $this->query_args['meta_query'], array( $role__in_clauses ) );
|
|
|
|
$this->custom_filters_in_query[ $field ] = $value;
|
|
} else {
|
|
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 );
|
|
}
|
|
$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 ) ) );
|
|
$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 ) ) );
|
|
|
|
$meta_query = array(
|
|
array(
|
|
'key' => 'birth_date',
|
|
'value' => array( $to_date, $from_date ),
|
|
'compare' => 'BETWEEN',
|
|
'type' => 'DATE',
|
|
'inclusive' => true,
|
|
),
|
|
);
|
|
|
|
$this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( $meta_query ) );
|
|
|
|
$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:i:s', strtotime( date( 'Y-m-d H:i:s', min( $value ) ) . "+$offset hours" ) );
|
|
$to_date = date( 'Y-m-d H:i:s', strtotime( date( 'Y-m-d H:i:s', max( $value ) ) . "+$offset hours" ) );
|
|
|
|
$date_query = array(
|
|
array(
|
|
'column' => 'user_registered',
|
|
'before' => $to_date,
|
|
'after' => $from_date,
|
|
'inclusive' => true,
|
|
),
|
|
);
|
|
|
|
if ( empty( $this->query_args['date_query'] ) ) {
|
|
$this->query_args['date_query'] = $date_query;
|
|
} else {
|
|
$this->query_args['date_query'] = array_merge( $this->query_args['date_query'], array( $date_query ) );
|
|
}
|
|
|
|
$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
|
|
$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 ) ),
|
|
'compare' => 'BETWEEN',
|
|
'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;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Set default filters
|
|
*
|
|
* @param $directory_data
|
|
*/
|
|
public function default_filters( $directory_data ) {
|
|
$default_filters = array();
|
|
if ( ! empty( $directory_data['search_filters'] ) ) {
|
|
$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 ) ) {
|
|
return;
|
|
}
|
|
|
|
foreach ( $default_filters as $field => $value ) {
|
|
|
|
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':
|
|
$field_query = array(
|
|
'key' => $field,
|
|
'value' => $value,
|
|
'compare' => apply_filters( 'um_members_directory_filter_text', '=', $field ),
|
|
);
|
|
break;
|
|
|
|
case 'select':
|
|
if ( ! is_array( $value ) ) {
|
|
$value = array( $value );
|
|
}
|
|
|
|
/** 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' => '=',
|
|
),
|
|
array(
|
|
'key' => $field,
|
|
'value' => serialize( (string) $single_val ),
|
|
'compare' => 'LIKE',
|
|
),
|
|
array(
|
|
'key' => $field,
|
|
'value' => '"' . $single_val . '"',
|
|
'compare' => 'LIKE',
|
|
),
|
|
);
|
|
|
|
if ( is_numeric( $single_val ) ) {
|
|
|
|
$arr_meta_query[] = array(
|
|
'key' => $field,
|
|
'value' => serialize( absint( $single_val ) ),
|
|
'compare' => 'LIKE',
|
|
);
|
|
|
|
}
|
|
|
|
$field_query = array_merge( $field_query, $arr_meta_query );
|
|
}
|
|
|
|
break;
|
|
case 'slider':
|
|
$field_query = array(
|
|
'key' => $field,
|
|
'value' => $value,
|
|
'compare' => 'BETWEEN',
|
|
'inclusive' => true,
|
|
);
|
|
break;
|
|
|
|
case 'datepicker':
|
|
$offset = 0;
|
|
if ( is_numeric( $gmt_offset ) ) {
|
|
$offset = $gmt_offset;
|
|
}
|
|
|
|
if ( ! empty( $value[0] ) ) {
|
|
$min = $value[0];
|
|
} else {
|
|
$range = $this->datepicker_filters_range( $field );
|
|
$min = strtotime( gmdate( 'Y/m/d', $range[0] ) );
|
|
}
|
|
if ( ! empty( $value[1] ) ) {
|
|
$max = $value[1];
|
|
} else {
|
|
$max = strtotime( gmdate( 'Y/m/d' ) );
|
|
}
|
|
|
|
$from_date = (int) $min + ( $offset * HOUR_IN_SECONDS ); // client time zone offset
|
|
$to_date = (int) $max + ( $offset * HOUR_IN_SECONDS ) + DAY_IN_SECONDS - 1; // time 23:59
|
|
|
|
$field_query = array(
|
|
'key' => $field,
|
|
'value' => array( $from_date, $to_date ),
|
|
'compare' => 'BETWEEN',
|
|
'inclusive' => true,
|
|
);
|
|
|
|
break;
|
|
case 'timepicker':
|
|
if ( ! empty( $value[0] ) ) {
|
|
$value[0] = $value[0] . ':00';
|
|
} else {
|
|
$range = $this->timepicker_filters_range( $field );
|
|
$value[0] = $range[0] . ':00';
|
|
}
|
|
if ( ! empty( $value[1] ) ) {
|
|
$value[1] = $value[1] . ':00';
|
|
} else {
|
|
$range = $this->timepicker_filters_range( $field );
|
|
$value[1] = $range[1] . ':00';
|
|
}
|
|
|
|
if ( $value[0] === $value[1] ) {
|
|
$field_query = array(
|
|
'key' => $field,
|
|
'value' => $value[0],
|
|
);
|
|
} else {
|
|
$field_query = array(
|
|
'key' => $field,
|
|
'value' => $value,
|
|
'compare' => 'BETWEEN',
|
|
'type' => 'TIME',
|
|
'inclusive' => true,
|
|
);
|
|
}
|
|
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 = is_array( $value ) ? $value : explode( '||', $value );
|
|
$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 );
|
|
}
|
|
$this->query_args['role__in'] = array_merge( $default_role, $um_role );
|
|
} else {
|
|
$this->query_args['role__in'] = $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 ) ) );
|
|
|
|
$meta_query = array(
|
|
array(
|
|
'key' => 'birth_date',
|
|
'value' => array( $to_date, $from_date ),
|
|
'compare' => 'BETWEEN',
|
|
'type' => 'DATE',
|
|
'inclusive' => true,
|
|
),
|
|
);
|
|
|
|
$this->query_args['meta_query'] = array_merge( $this->query_args['meta_query'], array( $meta_query ) );
|
|
|
|
break;
|
|
case 'user_registered':
|
|
$offset = 0;
|
|
if ( is_numeric( $gmt_offset ) ) {
|
|
$offset = $gmt_offset;
|
|
}
|
|
|
|
$from_date = date( 'Y-m-d H:i:s', strtotime( date( 'Y-m-d H:i:s', min( $value ) ) . "+$offset hours" ) );
|
|
$to_date = date( 'Y-m-d H:i:s', strtotime( date( 'Y-m-d H:i:s', max( $value ) ) . "+$offset hours" ) );
|
|
|
|
$date_query = array(
|
|
array(
|
|
'column' => 'user_registered',
|
|
'before' => $to_date,
|
|
'after' => $from_date,
|
|
'inclusive' => true,
|
|
),
|
|
);
|
|
|
|
if ( empty( $this->query_args['date_query'] ) ) {
|
|
$this->query_args['date_query'] = $date_query;
|
|
} else {
|
|
$this->query_args['date_query'] = array_merge( $this->query_args['date_query'], array( $date_query ) );
|
|
}
|
|
|
|
break;
|
|
case 'last_login':
|
|
$offset = 0;
|
|
if ( is_numeric( $gmt_offset ) ) {
|
|
$offset = $gmt_offset;
|
|
}
|
|
|
|
$value = array_map(
|
|
function( $date ) {
|
|
return is_numeric( $date ) ? $date : strtotime( $date );
|
|
},
|
|
$value
|
|
);
|
|
|
|
if ( ! empty( $value[0] ) ) {
|
|
$min = $value[0];
|
|
} else {
|
|
$range = $this->datepicker_filters_range( 'last_login' );
|
|
$min = strtotime( gmdate( 'Y/m/d', $range[0] ) );
|
|
}
|
|
if ( ! empty( $value[1] ) ) {
|
|
$max = $value[1];
|
|
} else {
|
|
$max = strtotime( gmdate( 'Y/m/d' ) );
|
|
}
|
|
|
|
$from_date = gmdate( 'Y-m-d H:i:s', (int) $min + ( $offset * HOUR_IN_SECONDS ) ); // client time zone offset
|
|
$to_date = gmdate( 'Y-m-d H:i:s', (int) $max + ( $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 ),
|
|
'compare' => 'BETWEEN',
|
|
'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 ) );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 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'] ) ? absint( $_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 ( wp_is_mobile() && 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;
|
|
}
|
|
|
|
/**
|
|
* @param int $user_id
|
|
*
|
|
* @return array
|
|
*/
|
|
private function build_user_actions_list( $user_id ) {
|
|
$actions = array();
|
|
if ( ! is_user_logged_in() ) {
|
|
return $actions;
|
|
}
|
|
|
|
if ( get_current_user_id() !== $user_id ) {
|
|
if ( UM()->roles()->um_current_user_can( 'edit', $user_id ) ) {
|
|
$actions['um-editprofile'] = array(
|
|
'title' => esc_html__( 'Edit Profile', 'ultimate-member' ),
|
|
'url' => um_edit_profile_url(),
|
|
);
|
|
}
|
|
|
|
$admin_actions = UM()->frontend()->users()->get_actions_list( $user_id );
|
|
if ( ! empty( $admin_actions ) ) {
|
|
foreach ( $admin_actions as $id => $arr ) {
|
|
$url = add_query_arg(
|
|
array(
|
|
'um_action' => $id,
|
|
'uid' => $user_id,
|
|
'nonce' => wp_create_nonce( $id . $user_id ),
|
|
),
|
|
um_user_profile_url( $user_id )
|
|
);
|
|
|
|
$actions[ $id ] = array(
|
|
'title' => esc_html( $arr['label'] ),
|
|
'url' => esc_url( $url ),
|
|
);
|
|
}
|
|
}
|
|
|
|
$actions = apply_filters( 'um_member_directory_users_card_actions', $actions, $user_id );
|
|
} else {
|
|
if ( empty( UM()->user()->cannot_edit ) ) {
|
|
$actions['um-editprofile'] = array(
|
|
'title' => esc_html__( 'Edit Profile', 'ultimate-member' ),
|
|
'url' => um_edit_profile_url(),
|
|
);
|
|
}
|
|
|
|
$actions['um-myaccount'] = array(
|
|
'title' => esc_html__( 'My Account', 'ultimate-member' ),
|
|
'url' => um_get_core_page( 'account' ),
|
|
);
|
|
|
|
$actions['um-logout'] = array(
|
|
'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;
|
|
}
|
|
|
|
/**
|
|
* @param int $user_id
|
|
* @param array $directory_data
|
|
*
|
|
* @return array
|
|
*/
|
|
public function build_user_card_data( $user_id, $directory_data ) {
|
|
um_fetch_user( $user_id );
|
|
|
|
$dropdown_actions = $this->build_user_actions_list( $user_id );
|
|
|
|
$actions = array();
|
|
$can_edit = UM()->roles()->um_current_user_can( 'edit', $user_id );
|
|
|
|
// Replace hook 'um_members_just_after_name'
|
|
ob_start();
|
|
do_action( 'um_members_just_after_name', $user_id, $directory_data );
|
|
$hook_just_after_name = ob_get_clean();
|
|
|
|
// Replace hook 'um_members_after_user_name'
|
|
ob_start();
|
|
do_action( 'um_members_after_user_name', $user_id, $directory_data );
|
|
$hook_after_user_name = ob_get_clean();
|
|
|
|
$data_array = array(
|
|
'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()->common()->users()->get_status( $user_id ) ),
|
|
'account_status_name' => esc_html( UM()->common()->users()->get_status( $user_id, 'formatted' ) ),
|
|
'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'] ) ) {
|
|
|
|
if ( ! empty( $directory_data['tagline_fields'] ) ) {
|
|
$directory_data['tagline_fields'] = maybe_unserialize( $directory_data['tagline_fields'] );
|
|
|
|
if ( is_array( $directory_data['tagline_fields'] ) ) {
|
|
foreach ( $directory_data['tagline_fields'] as $key ) {
|
|
if ( ! $key ) {
|
|
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 ] = wp_kses( $value, UM()->get_allowed_html( 'templates' ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( ! empty( $directory_data['show_userinfo'] ) ) {
|
|
|
|
if ( ! empty( $directory_data['reveal_fields'] ) ) {
|
|
|
|
$directory_data['reveal_fields'] = maybe_unserialize( $directory_data['reveal_fields'] );
|
|
|
|
if ( is_array( $directory_data['reveal_fields'] ) ) {
|
|
foreach ( $directory_data['reveal_fields'] as $key ) {
|
|
if ( ! $key ) {
|
|
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;
|
|
}
|
|
|
|
$label = UM()->fields()->get_label( $key );
|
|
if ( $key == 'role_select' || $key == 'role_radio' ) {
|
|
$label = strtr( $label, array(
|
|
' (Dropdown)' => '',
|
|
' (Radio)' => ''
|
|
) );
|
|
}
|
|
|
|
$data_array[ "label_{$key}" ] = esc_html__( $label, 'ultimate-member' );
|
|
$data_array[ $key ] = wp_kses( $value, UM()->get_allowed_html( 'templates' ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( ! empty( $directory_data['show_social'] ) ) {
|
|
ob_start();
|
|
UM()->fields()->show_social_urls();
|
|
$social_urls = ob_get_clean();
|
|
|
|
$data_array['social_urls'] = wp_kses( $social_urls, UM()->get_allowed_html( 'templates' ) );
|
|
}
|
|
}
|
|
|
|
$data_array = apply_filters( 'um_ajax_get_members_data', $data_array, $user_id, $directory_data );
|
|
|
|
um_reset_user_clean();
|
|
|
|
return $data_array;
|
|
}
|
|
|
|
|
|
/**
|
|
* Update limit query
|
|
*
|
|
* @param $user_query
|
|
*/
|
|
function pagination_changes( $user_query ) {
|
|
global $wpdb;
|
|
|
|
$directory_id = $this->get_directory_by_hash( sanitize_key( $_POST['directory_id'] ) );
|
|
$directory_data = UM()->query()->post_data( $directory_id );
|
|
|
|
$qv = $user_query->query_vars;
|
|
|
|
$number = $qv['number'];
|
|
if ( ! empty( $directory_data['max_users'] ) && $qv['paged']*$qv['number'] > $directory_data['max_users'] ) {
|
|
$number = ( $qv['paged']*$qv['number'] - ( $qv['paged']*$qv['number'] - $directory_data['max_users'] ) ) % $qv['number'];
|
|
}
|
|
|
|
// limit
|
|
if ( isset( $qv['number'] ) && $qv['number'] > 0 ) {
|
|
if ( $qv['offset'] ) {
|
|
$user_query->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['offset'], $number );
|
|
} else {
|
|
$user_query->query_limit = $wpdb->prepare( 'LIMIT %d, %d', $qv['number'] * ( $qv['paged'] - 1 ), $number );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function predefined_no_caps( $directory_data ) {
|
|
//predefined result for user without capabilities to see other members
|
|
if ( is_user_logged_in() && ! UM()->roles()->um_user_can( 'can_view_all' ) ) {
|
|
$pagination_data = array(
|
|
'pages_to_show' => array(),
|
|
'current_page' => 1,
|
|
'total_pages' => 0,
|
|
'total_users' => 0,
|
|
);
|
|
|
|
$pagination_data['header'] = $this->convert_tags( $directory_data['header'], $pagination_data );
|
|
$pagination_data['header_single'] = $this->convert_tags( $directory_data['header_single'], $pagination_data );
|
|
|
|
wp_send_json_success( array( 'users' => array(), 'pagination' => $pagination_data ) );
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Main Query function for getting members via AJAX
|
|
*/
|
|
function ajax_get_members() {
|
|
UM()->check_ajax_nonce();
|
|
|
|
global $wpdb;
|
|
|
|
if ( empty( $_POST['directory_id'] ) ) {
|
|
wp_send_json_error( __( 'Wrong member directory data', 'ultimate-member' ) );
|
|
}
|
|
|
|
$directory_id = $this->get_directory_by_hash( sanitize_key( $_POST['directory_id'] ) );
|
|
|
|
if ( empty( $directory_id ) ) {
|
|
wp_send_json_error( __( 'Wrong member directory data', 'ultimate-member' ) );
|
|
}
|
|
|
|
$directory_data = UM()->query()->post_data( $directory_id );
|
|
|
|
//predefined result for user without capabilities to see other members
|
|
$this->predefined_no_caps( $directory_data );
|
|
|
|
do_action( 'um_member_directory_before_query' );
|
|
|
|
// Prepare for BIG SELECT query
|
|
$wpdb->query( 'SET SQL_BIG_SELECTS=1' );
|
|
|
|
// Prepare default user query values
|
|
$this->query_args = array(
|
|
'fields' => 'ids',
|
|
'number' => 0,
|
|
'meta_query' => array(
|
|
'relation' => 'AND',
|
|
),
|
|
);
|
|
|
|
// handle different restrictions
|
|
$this->restriction_options();
|
|
|
|
// handle general options
|
|
$this->general_options( $directory_data );
|
|
|
|
// handle pagination options
|
|
$this->pagination_options( $directory_data );
|
|
|
|
// handle sorting options
|
|
$this->sorting_query( $directory_data );
|
|
|
|
// handle general search line
|
|
$this->general_search();
|
|
|
|
// handle filters
|
|
$this->filters( $directory_data );
|
|
|
|
$this->default_filters( $directory_data );
|
|
|
|
/**
|
|
* UM hook
|
|
*
|
|
* @type filter
|
|
* @title um_prepare_user_query_args
|
|
* @description Extend member directory query arguments
|
|
* @input_vars
|
|
* [{"var":"$query_args","type":"array","desc":"Members Query Arguments"},
|
|
* {"var":"$directory_settings","type":"array","desc":"Member Directory Settings"}]
|
|
* @change_log
|
|
* ["Since: 2.0"]
|
|
* @usage
|
|
* <?php add_filter( 'um_prepare_user_query_args', 'function_name', 10, 2 ); ?>
|
|
* @example
|
|
* <?php
|
|
* add_filter( 'um_prepare_user_query_args', 'my_prepare_user_query_args', 10, 2 );
|
|
* function my_prepare_user_query_args( $query_args, $directory_settings ) {
|
|
* // your code here
|
|
* return $query_args;
|
|
* }
|
|
* ?>
|
|
*/
|
|
$this->query_args = apply_filters( 'um_prepare_user_query_args', $this->query_args, $directory_data );
|
|
|
|
//unset empty meta_query attribute
|
|
if ( isset( $this->query_args['meta_query']['relation'] ) && count( $this->query_args['meta_query'] ) == 1 ) {
|
|
unset( $this->query_args['meta_query'] );
|
|
}
|
|
|
|
if ( isset( $this->query_args['role__in'] ) && empty( $this->query_args['role__in'] ) ) {
|
|
$member_directory_response = apply_filters( 'um_ajax_get_members_response', array(
|
|
'pagination' => $this->calculate_pagination( $directory_data, 0 ),
|
|
'users' => array(),
|
|
'is_search' => $this->is_search,
|
|
), $directory_data );
|
|
|
|
wp_send_json_success( $member_directory_response );
|
|
}
|
|
/**
|
|
* Fires just before the users query for getting users in member directory.
|
|
*
|
|
* @since 1.3.x
|
|
* @since 2.1.0 Added `$member_directory_class` variable.
|
|
* @hook um_user_before_query
|
|
*
|
|
* @param {array} $args Query arguments.
|
|
* @param {object} $member_directory_class Member Directory class. Since 2.1.0 version.
|
|
*
|
|
* @example <caption>Add custom arguments for query.</caption>
|
|
* function my_user_before_query( $query_args, $md_class ) {
|
|
* $query_args['{custom_key}'] = 'custom_value';
|
|
* }
|
|
* add_action( 'um_user_before_query', 'my_user_before_query', 10, 2 );
|
|
*/
|
|
do_action( 'um_user_before_query', $this->query_args, $this );
|
|
|
|
add_filter( 'get_meta_sql', array( &$this, 'change_meta_sql' ), 10, 6 );
|
|
|
|
add_filter( 'pre_user_query', array( &$this, 'pagination_changes' ), 10, 1 );
|
|
|
|
$user_query = new WP_User_Query( $this->query_args );
|
|
|
|
remove_filter( 'pre_user_query', array( &$this, 'pagination_changes' ), 10 );
|
|
|
|
remove_filter( 'get_meta_sql', array( &$this, 'change_meta_sql' ), 10 );
|
|
|
|
/**
|
|
* Fires just after the users query for getting users in member directory.
|
|
*
|
|
* @since 1.3.x
|
|
* @hook um_user_after_query
|
|
*
|
|
* @param {array} $query_args Query arguments.
|
|
* @param {object} $user_query Query results.
|
|
*
|
|
* @example <caption>Make some custom action after getting the users in member directory.</caption>
|
|
* function my_user_after_query( $query_args, $user_query ) {
|
|
* // your code here
|
|
* }
|
|
* add_action( 'um_user_after_query', 'my_user_after_query', 10, 2 );
|
|
*/
|
|
do_action( 'um_user_after_query', $this->query_args, $user_query );
|
|
|
|
$pagination_data = $this->calculate_pagination( $directory_data, $user_query->total_users );
|
|
|
|
$user_ids = ! empty( $user_query->results ) ? array_unique( $user_query->results ) : array();
|
|
|
|
/**
|
|
* Filters the member directory query result.
|
|
*
|
|
* @since 2.0
|
|
* @hook um_prepare_user_results_array
|
|
*
|
|
* @param {array} $user_ids Members Query Result.
|
|
* @param {array} $query_args Query arguments.
|
|
*
|
|
* @return {array} Query result.
|
|
*
|
|
* @example <caption>Remove some users where ID equals 10 and 12 from query.</caption>
|
|
* function my_custom_um_prepare_user_results_array( $user_ids, $query_args ) {
|
|
* $user_ids = array_diff( $user_ids, array( 10, 12 ) );
|
|
* return $user_ids;
|
|
* }
|
|
* add_filter( 'um_prepare_user_results_array', 'my_custom_um_prepare_user_results_array', 10, 2 );
|
|
*/
|
|
$user_ids = apply_filters( 'um_prepare_user_results_array', $user_ids, $this->query_args );
|
|
|
|
$sizes = UM()->options()->get( 'cover_thumb_sizes' );
|
|
|
|
$this->cover_size = wp_is_mobile() ? $sizes[1] : end( $sizes );
|
|
|
|
$this->cover_size = apply_filters( 'um_member_directory_cover_image_size', $this->cover_size, $directory_data );
|
|
|
|
$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 );
|
|
|
|
$users = array();
|
|
foreach ( $user_ids as $user_id ) {
|
|
$users[] = $this->build_user_card_data( $user_id, $directory_data );
|
|
}
|
|
|
|
um_reset_user();
|
|
// end of user card
|
|
|
|
$member_directory_response = apply_filters( 'um_ajax_get_members_response', array(
|
|
'pagination' => $pagination_data,
|
|
'users' => $users,
|
|
'is_search' => $this->is_search,
|
|
), $directory_data );
|
|
|
|
wp_send_json_success( $member_directory_response );
|
|
}
|
|
|
|
|
|
/**
|
|
* New menu
|
|
*
|
|
* @param string $element
|
|
* @param string $trigger
|
|
* @param array $items
|
|
* @param string $parent
|
|
*/
|
|
function dropdown_menu( $element, $trigger, $items = array(), $parent = '' ) {
|
|
// !!!!Important: all links in the dropdown items must have "class" attribute
|
|
?>
|
|
|
|
<div class="um-new-dropdown" data-element="<?php echo $element; ?>" data-trigger="<?php echo $trigger; ?>" data-parent="<?php echo $parent; ?>">
|
|
<ul>
|
|
<?php foreach ( $items as $k => $v ) { ?>
|
|
<li><?php echo $v; ?></li>
|
|
<?php } ?>
|
|
</ul>
|
|
</div>
|
|
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* New menu JS
|
|
*
|
|
* @param string $element
|
|
* @param string $trigger
|
|
* @param string $item
|
|
* @param string $additional_attributes
|
|
* @param string $parent
|
|
*/
|
|
function dropdown_menu_js( $element, $trigger, $item, $additional_attributes = '', $parent = '' ) {
|
|
?>
|
|
|
|
<div class="um-new-dropdown" data-element="<?php echo $element; ?>" data-trigger="<?php echo $trigger; ?>" data-parent="<?php echo $parent; ?>">
|
|
<ul>
|
|
<# _.each( <?php echo $item; ?>.dropdown_actions, function( action, key, list ) { #>
|
|
<li><a href="<# if ( typeof action.url != 'undefined' ) { #>{{{action.url}}}<# } else { #>javascript:void(0);<# }#>" class="{{{key}}}"<?php echo $additional_attributes ? " $additional_attributes" : '' ?>>{{{action.title}}}</a></li>
|
|
<# }); #>
|
|
</ul>
|
|
</div>
|
|
|
|
<?php
|
|
}
|
|
|
|
|
|
/**
|
|
* AJAX handler - Get options for the member directory "Admin filtering"
|
|
* @version 2.1.12
|
|
*/
|
|
function default_filter_settings() {
|
|
UM()->admin()->check_ajax_nonce();
|
|
|
|
// we can't use function "sanitize_key" because it changes uppercase to lowercase
|
|
$filter_key = sanitize_text_field( $_REQUEST['key'] );
|
|
$directory_id = absint( $_REQUEST['directory_id'] );
|
|
|
|
$html = $this->show_filter( $filter_key, array( 'form_id' => $directory_id ), false, true );
|
|
|
|
wp_send_json_success( array( 'field_html' => $html ) );
|
|
}
|
|
|
|
/**
|
|
* Get member directory id by page id.
|
|
*
|
|
* @param int $page_id Page ID.
|
|
*
|
|
* @return array Member directories ID.
|
|
*/
|
|
public function get_member_directory_id( $page_id ) {
|
|
$members_page = get_post( $page_id );
|
|
if ( ! empty( $members_page ) && ! is_wp_error( $members_page ) ) {
|
|
if ( ! empty( $members_page->post_content ) ) {
|
|
preg_match_all( '/\[ultimatemember[^\]]*?form_id\=[\'"]*?(\d+)[\'"]*?/i', $members_page->post_content, $matches );
|
|
if ( ! empty( $matches[1] ) && is_array( $matches[1] ) ) {
|
|
$member_directory_ids = array_map( 'absint', $matches[1] );
|
|
return $member_directory_ids;
|
|
}
|
|
}
|
|
}
|
|
|
|
return array();
|
|
}
|
|
}
|
|
}
|