class-acf-ajax-check-screen.php
2 months ago
class-acf-ajax-local-json-diff.php
1 year ago
class-acf-ajax-query-users.php
3 months ago
class-acf-ajax-query.php
4 months ago
class-acf-ajax-upgrade.php
2 months ago
class-acf-ajax-user-setting.php
1 year ago
class-acf-ajax.php
1 year ago
index.php
1 year ago
class-acf-ajax-query-users.php
310 lines
| 1 | <?php |
| 2 | |
| 3 | if ( ! defined( 'ABSPATH' ) ) { |
| 4 | exit; // Exit if accessed directly |
| 5 | } |
| 6 | |
| 7 | if ( ! class_exists( 'ACF_Ajax_Query_Users' ) ) : |
| 8 | |
| 9 | class ACF_Ajax_Query_Users extends ACF_Ajax_Query { |
| 10 | |
| 11 | /** @var string The AJAX action name. */ |
| 12 | var $action = 'acf/ajax/query_users'; |
| 13 | |
| 14 | /** |
| 15 | * Verifies the request. |
| 16 | * |
| 17 | * @since ACF 6.3.2 |
| 18 | * |
| 19 | * @param array $request The request args. |
| 20 | * @return (bool|WP_Error) True on success, WP_Error on fail. |
| 21 | */ |
| 22 | public function verify_request( $request ) { |
| 23 | if ( empty( $request['nonce'] ) || empty( $request['field_key'] ) ) { |
| 24 | return new WP_Error( 'acf_invalid_args', __( 'Invalid request args.', 'secure-custom-fields' ), array( 'status' => 404 ) ); |
| 25 | } |
| 26 | |
| 27 | $nonce = $request['nonce']; |
| 28 | $action = $request['field_key']; |
| 29 | $field_action = true; |
| 30 | |
| 31 | if ( isset( $request['conditional_logic'] ) && true === (bool) $request['conditional_logic'] ) { |
| 32 | if ( ! acf_current_user_can_admin() ) { |
| 33 | return new WP_Error( 'acf_invalid_permissions', __( 'Sorry, you do not have permission to do that.', 'secure-custom-fields' ) ); |
| 34 | } |
| 35 | |
| 36 | // Use the standard ACF admin nonce. |
| 37 | $nonce = ''; |
| 38 | $action = ''; |
| 39 | $field_action = false; |
| 40 | } |
| 41 | |
| 42 | if ( ! acf_verify_ajax( $nonce, $action, $field_action ) ) { |
| 43 | return new WP_Error( 'acf_invalid_nonce', __( 'Invalid nonce.', 'secure-custom-fields' ), array( 'status' => 404 ) ); |
| 44 | } |
| 45 | |
| 46 | return true; |
| 47 | } |
| 48 | |
| 49 | /** |
| 50 | * init_request |
| 51 | * |
| 52 | * Called at the beginning of a request to setup properties. |
| 53 | * |
| 54 | * @date 23/5/19 |
| 55 | * @since ACF 5.8.1 |
| 56 | * |
| 57 | * @param array $request The request args. |
| 58 | * @return void |
| 59 | */ |
| 60 | function init_request( $request ) { |
| 61 | parent::init_request( $request ); |
| 62 | |
| 63 | // Customize query. |
| 64 | add_filter( 'user_search_columns', array( $this, 'filter_search_columns' ), 10, 3 ); |
| 65 | |
| 66 | /** |
| 67 | * Fires when a request is made. |
| 68 | * |
| 69 | * @date 21/5/19 |
| 70 | * @since ACF 5.8.1 |
| 71 | * |
| 72 | * @param array $request The query request. |
| 73 | * @param ACF_Ajax_Query $query The query object. |
| 74 | */ |
| 75 | do_action( 'acf/ajax/query_users/init', $request, $this ); |
| 76 | } |
| 77 | |
| 78 | /** |
| 79 | * Returns an array of args for this query. |
| 80 | * |
| 81 | * @since ACF 5.7.2 |
| 82 | * |
| 83 | * @param array $request The request args. |
| 84 | * @return array |
| 85 | */ |
| 86 | public function get_args( $request ) { |
| 87 | $args = array( |
| 88 | 'number' => $this->per_page, |
| 89 | 'paged' => $this->page, |
| 90 | ); |
| 91 | |
| 92 | if ( $this->is_search ) { |
| 93 | $args['search'] = "*{$this->search}*"; |
| 94 | } |
| 95 | |
| 96 | /** |
| 97 | * Filters the query args. |
| 98 | * |
| 99 | * @since ACF 5.8.1 |
| 100 | * |
| 101 | * @param array $args The query args. |
| 102 | * @param array $request The query request. |
| 103 | * @param ACF_Ajax_Query $query The query object. |
| 104 | */ |
| 105 | return apply_filters( 'acf/ajax/query_users/args', $args, $request, $this ); |
| 106 | } |
| 107 | |
| 108 | /** |
| 109 | * Prepares args for the get_results() method. |
| 110 | * |
| 111 | * @date 23/3/20 |
| 112 | * @since ACF 5.8.9 |
| 113 | * |
| 114 | * @param array args The query args. |
| 115 | * @return array |
| 116 | */ |
| 117 | function prepare_args( $args ) { |
| 118 | |
| 119 | // Parse pagination args that may have been modified. |
| 120 | if ( isset( $args['users_per_page'] ) ) { |
| 121 | $this->per_page = intval( $args['users_per_page'] ); |
| 122 | unset( $args['users_per_page'] ); |
| 123 | } elseif ( isset( $args['number'] ) ) { |
| 124 | $this->per_page = intval( $args['number'] ); |
| 125 | } |
| 126 | |
| 127 | if ( isset( $args['paged'] ) ) { |
| 128 | $this->page = intval( $args['paged'] ); |
| 129 | unset( $args['paged'] ); |
| 130 | } |
| 131 | |
| 132 | // Set pagination args for fine control. |
| 133 | $args['number'] = $this->per_page; |
| 134 | $args['offset'] = $this->per_page * ( $this->page - 1 ); |
| 135 | $args['count_total'] = true; |
| 136 | return $args; |
| 137 | } |
| 138 | |
| 139 | /** |
| 140 | * Returns an array of results for the given args. |
| 141 | * |
| 142 | * @since ACF 5.7.2 |
| 143 | * |
| 144 | * @param array $args The query args. |
| 145 | * @return array |
| 146 | */ |
| 147 | public function get_results( $args ) { |
| 148 | // Prepare the $args for query. |
| 149 | $args = $this->prepare_args( $args ); |
| 150 | $results = array(); |
| 151 | |
| 152 | // Apply field role restriction, allowing overrides via filter. |
| 153 | if ( $this->field && ! empty( $this->field['role'] ) && empty( $args['role__in'] ) ) { |
| 154 | $args['role__in'] = (array) $this->field['role']; |
| 155 | } |
| 156 | |
| 157 | // Get result groups. |
| 158 | if ( ! empty( $args['role__in'] ) ) { |
| 159 | $roles = acf_get_user_role_labels( $args['role__in'] ); |
| 160 | } else { |
| 161 | $roles = acf_get_user_role_labels(); |
| 162 | } |
| 163 | |
| 164 | // Return a flat array of results when searching or when querying one group only. |
| 165 | if ( $this->is_search || count( $roles ) === 1 ) { |
| 166 | |
| 167 | // Query users and append to results. |
| 168 | $wp_user_query = new WP_User_Query( $args ); |
| 169 | $users = (array) $wp_user_query->get_results(); |
| 170 | $total_users = $wp_user_query->get_total(); |
| 171 | foreach ( $users as $user ) { |
| 172 | $results[] = $this->get_result( $user ); |
| 173 | } |
| 174 | |
| 175 | // Determine if more results exist. |
| 176 | // As this query does not return grouped results, the calculation can be exact (">"). |
| 177 | $this->more = ( $total_users > count( $users ) + $args['offset'] ); |
| 178 | // Otherwise, group results via role. |
| 179 | } else { |
| 180 | |
| 181 | // Unset args that will interfere with query results. |
| 182 | unset( $args['role__in'], $args['role__not_in'] ); |
| 183 | |
| 184 | $args['search'] = $this->search ? $this->search : ''; |
| 185 | |
| 186 | // Loop over each role. |
| 187 | foreach ( $roles as $role => $role_label ) { |
| 188 | |
| 189 | // Query users (for this role only). |
| 190 | $args['role'] = $role; |
| 191 | $wp_user_query = new WP_User_Query( $args ); |
| 192 | $users = (array) $wp_user_query->get_results(); |
| 193 | $total_users = $wp_user_query->get_total(); |
| 194 | |
| 195 | // acf_log( $args ); |
| 196 | // acf_log( '- ', count($users) ); |
| 197 | // acf_log( '- ', $total_users ); |
| 198 | // If users were found for this query... |
| 199 | if ( $users ) { |
| 200 | |
| 201 | // Append optgroup of results. |
| 202 | $role_results = array(); |
| 203 | foreach ( $users as $user ) { |
| 204 | $role_results[] = $this->get_result( $user ); |
| 205 | } |
| 206 | $results[] = array( |
| 207 | 'text' => $role_label, |
| 208 | 'children' => $role_results, |
| 209 | ); |
| 210 | |
| 211 | // End loop when enough results have been found. |
| 212 | if ( count( $users ) === $args['number'] ) { |
| 213 | |
| 214 | // Determine if more results exist. |
| 215 | // As this query does return grouped results, the calculation is best left fuzzy to avoid querying the next group (">="). |
| 216 | $this->more = ( $total_users >= count( $users ) + $args['offset'] ); |
| 217 | break; |
| 218 | |
| 219 | // Otherwise, modify the args so that the next query can continue on correctly. |
| 220 | } else { |
| 221 | $args['offset'] = 0; |
| 222 | $args['number'] -= count( $users ); |
| 223 | } |
| 224 | |
| 225 | // If no users were found (for the current pagination args), but there were users found for previous pages... |
| 226 | // Modify the args so that the next query is offset slightly less (the number of total users) and can continue on correctly. |
| 227 | } elseif ( $total_users ) { |
| 228 | $args['offset'] -= $total_users; |
| 229 | continue; |
| 230 | |
| 231 | // Ignore roles that will never return a result. |
| 232 | } else { |
| 233 | continue; |
| 234 | } |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | /** |
| 239 | * Filters the query results. |
| 240 | * |
| 241 | * @date 21/5/19 |
| 242 | * @since ACF 5.8.1 |
| 243 | * |
| 244 | * @param array $results The query results. |
| 245 | * @param array $args The query args. |
| 246 | * @param ACF_Ajax_Query $query The query object. |
| 247 | */ |
| 248 | return apply_filters( 'acf/ajax/query_users/results', $results, $args, $this ); |
| 249 | } |
| 250 | |
| 251 | /** |
| 252 | * get_result |
| 253 | * |
| 254 | * Returns a single result for the given item object. |
| 255 | * |
| 256 | * @date 31/7/18 |
| 257 | * @since ACF 5.7.2 |
| 258 | * |
| 259 | * @param mixed $item A single item from the queried results. |
| 260 | * @return string |
| 261 | */ |
| 262 | function get_result( $user ) { |
| 263 | $item = acf_get_user_result( $user ); |
| 264 | |
| 265 | /** |
| 266 | * Filters the result item. |
| 267 | * |
| 268 | * @date 21/5/19 |
| 269 | * @since ACF 5.8.1 |
| 270 | * |
| 271 | * @param array $item The choice id and text. |
| 272 | * @param ACF_User $user The user object. |
| 273 | * @param ACF_Ajax_Query $query The query object. |
| 274 | */ |
| 275 | return apply_filters( 'acf/ajax/query_users/result', $item, $user, $this ); |
| 276 | } |
| 277 | |
| 278 | /** |
| 279 | * Filters the WP_User_Query search columns. |
| 280 | * |
| 281 | * @since ACF 5.8.8 |
| 282 | * |
| 283 | * @param array $columns An array of column names to be searched. |
| 284 | * @param string $search The search term. |
| 285 | * @param WP_User_Query $WP_User_Query The WP_User_Query instance. |
| 286 | * @return array |
| 287 | */ |
| 288 | public function filter_search_columns( $columns, $search, $WP_User_Query ) { |
| 289 | // Restrict search columns for users that can't edit other users. |
| 290 | if ( ! current_user_can( 'edit_users' ) ) { |
| 291 | $columns = array( 'user_login', 'user_nicename', 'display_name' ); |
| 292 | } |
| 293 | |
| 294 | /** |
| 295 | * Filters the column names to be searched. |
| 296 | * |
| 297 | * @since ACF 5.8.1 |
| 298 | * |
| 299 | * @param array $columns An array of column names to be searched. |
| 300 | * @param string $search The search term. |
| 301 | * @param WP_User_Query $WP_User_Query The WP_User_Query instance. |
| 302 | * @param ACF_Ajax_Query $query The query object. |
| 303 | */ |
| 304 | return apply_filters( 'acf/ajax/query_users/search_columns', $columns, $search, $WP_User_Query, $this ); |
| 305 | } |
| 306 | } |
| 307 | |
| 308 | acf_new_instance( 'ACF_Ajax_Query_Users' ); |
| 309 | endif; // class_exists check |
| 310 |