/** * User query (abstraction layer). * * @param array $args Query args. * * @return array ['query', 'pagination'] elements. */ public static function query($args = array()) { global $wpdb; if (!is_array($args)) { $args = array(); } $p_var = c_ws_plugin__s2member_pro_sc_member_list_in::p_var(); if (empty($_REQUEST[$p_var])) { $page = 1; // Default page number. } elseif (($page = (int) $_REQUEST[$p_var]) < 1) { $page = 1; // Default page number. } $original_args = $args; // Needed below. $default_args = array('blog_id' => $GLOBALS['blog_id'], 'role' => '', 'meta_key' => '', 'meta_value' => '', 'meta_compare' => '', 'meta_query' => array(), 'search' => '', 'search_columns' => array('ID', 'user_login', 'user_email', 'user_url', 'user_nicename', 'display_name', 'first_name', 'last_name', 'nickname'), 'include' => array(), 'exclude' => array(), 'order' => 'DESC', 'orderby' => 'registered', 'number' => 25); if (!empty($args['args'])) { $args = wp_parse_args($args['args']); $args = array_merge($default_args, $args); } else { // Merge with individual args. unset($args['args']); // Do not use. $args = array_merge($default_args, $args); } foreach ($args as $_key => &$_value) { if (in_array($_key, array('count_total'), true)) { $_value = filter_var($_value, FILTER_VALIDATE_BOOLEAN); } elseif (in_array($_key, array('blog_id', 'offset', 'number'), true)) { $_value = (int) $_value; } elseif (in_array($_key, array('meta_query', 'search_columns', 'include', 'exclude'), true)) { $_value = $_value ? (array) $_value : array(); } elseif (in_array($_key, array('fields'), true)) { $_value = is_array($_value) ? $_value : (string) $_value; } elseif (in_array($_key, array('role', 'search', 'who', 'meta_key', 'meta_value', 'meta_compare', 'order', 'orderby'), true)) { $_value = (string) $_value; } } unset($_key, $_value); // Housekeeping; must unset due to reference. /* ---------------------------------------------------------- */ $first_last_name_meta_queries = array('relaton' => 'AND', 'first_name' => array('key' => 'first_name', 'value' => '___', 'compare' => '!='), 'last_name' => array('key' => 'last_name', 'value' => '___', 'compare' => '!='), 'nickname' => array('key' => 'nickname', 'value' => '___', 'compare' => '!=')); if ($args['meta_query']) { $args['meta_query'] = array('relation' => 'AND', $args['meta_query'], $first_last_name_meta_queries); } else { $args['meta_query'] = $first_last_name_meta_queries; } /* ---------------------------------------------------------- */ if (strpos(trim($args['search'], "* \t\n\r\v"), '*') !== false) { $args['search'] = '"' . str_replace('*', '', $args['search']) . '"'; // Do not allow `*` to appear in the middle of a string. // This is currently unsupported by WP_User_Query. // It also creates a problem w/ usermeta regex below. } if (strlen($args['search']) >= 2 && strpos($args['search'], '*') === false && strpos($args['search'], '"') === false) { $args['search'] = '*' . $args['search'] . '*'; } $args['search'] = trim($args['search'], '"' . " \t\n\r\v"); $search_regex = '^' . str_replace('\\*', '.*', preg_quote($args['search'])) . '$'; // Note that an ungreedy `.*?` is not possible. See: <http://jas.xyz/1PIWPZA> /* ---------------------------------------------------------- */ if (!$args['search_columns']) { // Use defaults? $args['search_columns'] = $default_args['search_columns']; } $user_search_cols = preg_grep('/^(?:ID|user_login|user_email|user_url|user_nicename|display_name)$/', $args['search_columns']); $s2_custom_field_search_cols = preg_grep('/^s2member_custom_field_\\w+$/', $args['search_columns']); $user_meta_search_cols = array_diff($args['search_columns'], $user_search_cols, $s2_custom_field_search_cols); self::$_search_columns_for_filter = $user_search_cols; // `wp_user` cols only. add_filter('user_search_columns', 'c_ws_plugin__s2member_pro_member_list::_search_columns_filter'); $blog_prefix = $wpdb->get_blog_prefix($args['blog_id']); // e.g., `wp_`, etc. foreach ($user_meta_search_cols as &$_search_col) { if (stripos($_search_col, 's2member_') === 0) { $_search_col = $blog_prefix . $_search_col; // e.g., `wp_s2member_subscr_id`. } // Stored as a user option key; i.e., as a blog-specific/prefixed metadata value. } unset($_search_col); // Housekeeping; must unset due to reference. /* ---------------------------------------------------------- */ $search_s2_custom_fields = true; // Default behavior. if (!$args['search']) { $search_s2_custom_fields = false; } elseif (!empty($original_args['search_columns']) && !$s2_custom_field_search_cols) { $search_s2_custom_fields = false; } /* ---------------------------------------------------------- */ // Convert this into a complex meta query w/ multiple dimensions. // See: <http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters> // Here we wrap what could potentially be a complex meta query already. if ($args['search'] && $search_regex && $user_meta_search_cols) { $user_meta_queries = array('relation' => 'OR'); foreach ($user_meta_search_cols as $_search_col) { $user_meta_queries[] = array('key' => $_search_col, 'value' => $search_regex, 'compare' => 'REGEXP'); } // unset($_search_col); // Housekeeping. if ($user_meta_queries && $args['meta_query']) { $args['meta_query'] = array('relation' => 'AND', $args['meta_query'], $user_meta_queries); } elseif ($user_meta_queries) { $args['meta_query'] = $user_meta_queries; } } /* ---------------------------------------------------------- */ $list_max = apply_filters('ws_plugin__s2member_pro_member_list_max', 250); $args['who'] = ''; $args['count_total'] = true; $args['fields'] = 'all_with_meta'; $args['number'] = min($args['number'], $list_max); $args['number'] = max(1, $args['number']); $args['offset'] = ($page - 1) * $args['number']; /* ---------------------------------------------------------- */ if ($args['search']) { $query_args = $args; $query_args['fields'] = 'ID'; $query_args['orderby'] = 'ID'; $query_args['order'] = 'ASC'; unset($query_args['number'], $query_args['offset']); $user_ids = array(); // Intialize. if ($user_search_cols) { $query_args['meta_query'] = $original_args['meta_query']; $query = new WP_User_Query($query_args); $user_ids = array_merge($user_ids, $query->get_results()); } if ($user_meta_search_cols) { unset($query_args['search']); $query_args['meta_query'] = $args['meta_query']; $query = new WP_User_Query($query_args); $user_ids = array_merge($user_ids, $query->get_results()); } remove_filter('user_search_columns', 'c_ws_plugin__s2member_pro_member_list::_search_columns_filter'); if ($search_s2_custom_fields) { // Also search in the serialized array of custom fields? if ($s2_custom_field_user_ids = self::search_s2_custom_fields($args, $s2_custom_field_search_cols)) { $user_ids = array_merge($user_ids, $s2_custom_field_user_ids); } } if (!($user_ids = array_unique($user_ids))) { return array('query' => new WP_User_Query(), 'pagination' => self::paginate($page, 0, $args['number'])); } $query_args = $args; $query_args['include'] = $user_ids; $query_args['fields'] = 'all_with_meta'; $query_args['meta_query'] = $original_args['meta_query']; unset($query_args['search'], $query_args['search_columns']); $query = new WP_User_Query($query_args); return array('query' => $query, 'pagination' => self::paginate($page, (int) $query->get_total(), $query_args['number'])); } else { // Default behavior; must faster. $query = new WP_User_Query($args); // Args as-is. remove_filter('user_search_columns', 'c_ws_plugin__s2member_pro_member_list::_search_columns_filter'); return array('query' => $query, 'pagination' => self::paginate($page, (int) $query->get_total(), $args['number'])); } }
/** * `[s2Member-List /]` Shortcode. * * @package s2Member\Shortcodes * @since 140504 * * @attaches-to ``add_shortcode('s2Member-List');`` * * @param array $attr An array of Attributes. * @param string $content Content inside the Shortcode. * @param string $shortcode The actual Shortcode name itself. * * @return mixed Template file output for this shortcode. */ public static function shortcode($attr = array(), $content = '', $shortcode = '') { $wpdb = $GLOBALS['wpdb']; /** @var $wpdb \wpdb For IDEs. */ $defaults = array('args' => '', 'blog' => $GLOBALS['blog_id'], 'rlc_satisfy' => 'ALL', 'role' => '', 'level' => '', 'ccap' => '', 'roles' => '', 'levels' => '', 'ccaps' => '', 'search' => '', 'search_columns' => '', 'enable_list_search' => '', 'include' => '', 'exclude' => '', 'order' => 'DESC', 'orderby' => 'registered', 'limit' => 25, 'template' => '', 'avatar_size' => 48, 'show_avatar' => 'yes', 'link_avatar' => '', 'show_display_name' => 'yes', 'link_display_name' => '', 'show_fields' => ''); if (!empty($attr['orderby']) && in_array($attr['orderby'], array('login', 'nicename', 'email', 'url', 'display_name'), TRUE)) { $defaults['order'] = 'ASC'; } // A more logical default when dealing with alphabetic ordering. $attr = shortcode_atts($defaults, $attr); if (!$attr['roles'] && $attr['role']) { $attr['roles'] = $attr['role']; } if (!isset($attr['levels'][0]) && isset($attr['level'][0])) { $attr['levels'] = $attr['level']; } if (!$attr['ccaps'] && $attr['ccap']) { $attr['ccaps'] = $attr['ccap']; } $attr['order'] = strtoupper($attr['order']); $attr['rlc_satisfy'] = strtoupper($attr['rlc_satisfy']); $attr['show_avatar'] = filter_var($attr['show_avatar'], FILTER_VALIDATE_BOOLEAN); $attr['show_display_name'] = filter_var($attr['show_display_name'], FILTER_VALIDATE_BOOLEAN); $attr['enable_list_search'] = filter_var($attr['enable_list_search'], FILTER_VALIDATE_BOOLEAN); if ($attr['args']) { // Custom args? $args = wp_parse_args($attr['args']); } else { $args = array('blog_id' => (int) $attr['blog'], 'meta_query' => array(), 'search' => $attr['search'], 'search_columns' => preg_split('/[;,\\s]+/', $attr['search_columns'], NULL, PREG_SPLIT_NO_EMPTY), 'include' => preg_split('/[;,\\s]+/', $attr['include'], NULL, PREG_SPLIT_NO_EMPTY), 'exclude' => preg_split('/[;,\\s]+/', $attr['exclude'], NULL, PREG_SPLIT_NO_EMPTY), 'order' => $attr['order'], 'orderby' => $attr['orderby'], 'number' => (int) $attr['limit']); if ($attr['roles']) { foreach (preg_split('/[;,\\s]+/', $attr['roles'], NULL, PREG_SPLIT_NO_EMPTY) as $_role) { $args['meta_query'][] = array('key' => $wpdb->get_blog_prefix() . 'capabilities', 'value' => '"' . $_role . '"', 'compare' => 'LIKE'); } if ($attr['rlc_satisfy'] === 'ANY') { // Default is `ALL` (i.e., `AND`). $args['meta_query']['relation'] = 'OR'; } unset($_role); // Housekeeping. } if ($attr['levels']) { foreach (preg_split('/[;,\\s]+/', $attr['levels'], NULL, PREG_SPLIT_NO_EMPTY) as $_level) { $args['meta_query'][] = array('key' => $wpdb->get_blog_prefix() . 'capabilities', 'value' => '"s2member_level' . $_level . '"', 'compare' => 'LIKE'); } if ($attr['rlc_satisfy'] === 'ANY') { // Default is `ALL` (i.e., `AND`). $args['meta_query']['relation'] = 'OR'; } unset($_level); // Housekeeping. } if ($attr['ccaps']) { foreach (preg_split('/[;,\\s]+/', $attr['ccaps'], NULL, PREG_SPLIT_NO_EMPTY) as $_ccap) { $args['meta_query'][] = array('key' => $wpdb->get_blog_prefix() . 'capabilities', 'value' => '"access_s2member_ccap_' . $_ccap . '"', 'compare' => 'LIKE'); } if ($attr['rlc_satisfy'] === 'ANY') { // Default is `ALL` (i.e., `AND`). $args['meta_query']['relation'] = 'OR'; } unset($_ccap); // Housekeeping. } } if (is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) { $args['blog_id'] = $GLOBALS['blog_id']; } // Disallow for security reasons. $s_var = self::s_var(); $p_var = self::p_var(); if ($attr['enable_list_search'] && !empty($_REQUEST[$s_var])) { $args['search'] = trim(stripslashes($_REQUEST[$s_var])); } $member_list_query = c_ws_plugin__s2member_pro_member_list::query($args); $custom_template = is_file(TEMPLATEPATH . '/member-list.php') ? TEMPLATEPATH . '/member-list.php' : ''; $custom_template = is_file(get_stylesheet_directory() . '/member-list.php') ? get_stylesheet_directory() . '/member-list.php' : $custom_template; $custom_template = $attr['template'] && is_file(TEMPLATEPATH . '/' . $attr['template']) ? TEMPLATEPATH . '/' . $attr['template'] : $custom_template; $custom_template = $attr['template'] && is_file(get_stylesheet_directory() . '/' . $attr['template']) ? get_stylesheet_directory() . '/' . $attr['template'] : $custom_template; $custom_template = $attr['template'] && is_file(WP_CONTENT_DIR . '/' . $attr['template']) ? WP_CONTENT_DIR . '/' . $attr['template'] : $custom_template; if ($attr['template'] && !$custom_template) { // Unable to locate the template file? trigger_error(sprintf('Invalid `template=""` attribute. Could not find: `%1$s`.', esc_html($attr['template'])), E_USER_ERROR); } $code = trim(file_get_contents($custom_template ? $custom_template : dirname(dirname(__FILE__)) . '/templates/members/member-list.php')); $code = trim(!$custom_template || !is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site() ? c_ws_plugin__s2member_utilities::evl($code, get_defined_vars()) : $code); return apply_filters('ws_plugin__s2member_pro_sc_member_list', $code, get_defined_vars()); }
/** * Members List; WP User Query wrapper. * * @param array $args Optional array of arguments to {@link \WP_User_Query} * * @return array Containing the following keys: `query` and `pagination`. */ public static function query($args = array()) { if (!is_array($args)) { $args = array(); } $p_var = c_ws_plugin__s2member_pro_sc_member_list_in::p_var(); if (empty($_REQUEST[$p_var]) || ($page = (int) $_REQUEST[$p_var]) < 1) { $page = 1; } // Default page number. $default_args = array('blog_id' => $GLOBALS['blog_id'], 'role' => '', 'meta_key' => '', 'meta_value' => '', 'meta_compare' => '', 'meta_query' => array(), 'search' => '', 'search_columns' => array('ID', 'user_login', 'user_email', 'user_url', 'user_nicename', 'display_name'), 'include' => array(), 'exclude' => array(), 'order' => 'DESC', 'orderby' => 'registered', 'number' => 25); $original_args = $args; // Useful in certain cases. // e.g., `if(empty($original_args['search_columns']))`. if (!empty($args['args'])) { $args = wp_parse_args($args['args']); $args = array_merge($default_args, $args); } else { unset($args['args']); // Do not use. $args = array_merge($default_args, $args); } foreach ($args as $_key => &$_value) { if (in_array($_key, array('count_total'), TRUE)) { $_value = filter_var($_value, FILTER_VALIDATE_BOOLEAN); } else { if (in_array($_key, array('blog_id', 'offset', 'number'), TRUE)) { $_value = (int) $_value; } else { if (in_array($_key, array('meta_query', 'search_columns', 'include', 'exclude'), TRUE)) { $_value = $_value ? (array) $_value : array(); } else { if (in_array($_key, array('fields'), TRUE)) { $_value = is_array($_value) ? $_value : (string) $_value; } else { if (in_array($_key, array('role', 'search', 'who', 'meta_key', 'meta_value', 'meta_compare', 'order', 'orderby'), TRUE)) { $_value = (string) $_value; } } } } } } unset($_key, $_value); // Housekeeping. /* ---------------------------------------------------------- */ if (strlen($args['search']) >= 2 && strpos($args['search'], '*') === FALSE && strpos($args['search'], '"') === FALSE) { $args['search'] = '*' . $args['search'] . '*'; } if (!$args['search_columns']) { // Use defaults? $args['search_columns'] = $default_args['search_columns']; } $search_s2_custom_fields = TRUE; // Default value. if (empty($args['search'])) { $search_s2_custom_fields = FALSE; } else { if (!empty($original_args['search_columns']) && !preg_grep('/(?:^|\\W)s2member_custom_field_\\w+/', $args['search_columns'])) { $search_s2_custom_fields = FALSE; } } /* ---------------------------------------------------------- */ $args['who'] = ''; $args['count_total'] = TRUE; $args['fields'] = 'all_with_meta'; $args['number'] = min($args['number'], apply_filters('ws_plugin__s2member_pro_member_list_max', 250, get_defined_vars())); if ($args['number'] < 1) { $args['number'] = 1; } // Make sure this is always >= 1. $args['offset'] = ($page - 1) * $args['number']; // Calculate dynamically. /* ---------------------------------------------------------- */ if ($search_s2_custom_fields) { $user_id_args = $args; $user_id_args['fields'] = 'ID'; $user_id_args['orderby'] = 'ID'; $user_id_args['order'] = 'ASC'; unset($user_id_args['number'], $user_id_args['offset']); self::$search_columns_for_filter = $user_id_args['search_columns']; add_filter('user_search_columns', 'c_ws_plugin__s2member_pro_member_list::_search_columns_filter'); $user_ids_query = new WP_User_Query($user_id_args); $user_ids = $user_ids_query->get_results(); $user_ids_from_s2_custom_fields = self::search_s2_custom_fields($user_id_args, $original_args); remove_filter('user_search_columns', 'c_ws_plugin__s2member_pro_member_list::_search_columns_filter'); if (!empty($user_ids_from_s2_custom_fields)) { $user_ids = array_merge($user_ids, $user_ids_from_s2_custom_fields); $user_ids = array_unique($user_ids); } if (!$user_ids) { // The search is already known to be empty? return array('query' => $user_ids_query, 'pagination' => self::paginate($page, 0, $args['number'])); } $user_id_args = $args; $user_id_args['include'] = $user_ids; $user_id_args['fields'] = 'all_with_meta'; unset($user_id_args['search'], $user_id_args['search_columns']); $user_ids_query = new WP_User_Query($user_id_args); return array('query' => $user_ids_query, 'pagination' => self::paginate($page, (int) $user_ids_query->get_total(), $user_id_args['number'])); } else { self::$search_columns_for_filter = $args['search_columns']; add_filter('user_search_columns', 'c_ws_plugin__s2member_pro_member_list::_search_columns_filter'); $query = new WP_User_Query($args); // Use args as configured already. remove_filter('user_search_columns', 'c_ws_plugin__s2member_pro_member_list::_search_columns_filter'); return array('query' => $query, 'pagination' => self::paginate($page, (int) $query->get_total(), $args['number'])); } }