namespace, '/' . $this->rest_base . '/(?P[\w-]+)', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [ $this, 'get_options' ], 'permission_callback' => [ $this, 'get_items_permissions_check' ], 'args' => [ 'type' => [ 'description' => 'The type of options to fetch.', 'type' => 'string', 'required' => true, ], 'search' => [ 'description' => 'Limit results to those matching a string.', 'type' => 'string', ], 'include' => [ 'description' => 'Ensure specific IDs are included in the results (e.g., for already selected items).', 'type' => 'array', 'items' => [ 'type' => 'integer' ], ], ], ], ] ); } /** * Permission check for the endpoint. * * @param WP_REST_Request $request * @return bool */ public function get_items_permissions_check( WP_REST_Request $request ): bool { return current_user_can( adpresso_get_capability( 'edit_ad' ) ); } /** * Main callback to fetch and return options based on the type. * * @param WP_REST_Request $request * * @return WP_REST_Response */ public function get_options( WP_REST_Request $request ): WP_REST_Response { $type = $request->get_param( 'type' ); $search = $request->get_param( 'search' ); $include_ids = $request->get_param( 'include' ); $options = []; switch ( $type ) { case 'users': case 'authors': $options = $this->search_users( $search, $include_ids ); break; } return new WP_REST_Response( $options, 200 ); } /** * Searches for users and formats them for a select control. * * @param string|null $search The search term. * @param array|null $include_ids An array of user IDs to ensure are included. * * @return array */ private function search_users( ?string $search, ?array $include_ids ): array { $results_map = []; $include_ids = array_map( 'intval', $include_ids ?? [] ); if ( ! empty( $include_ids ) ) { $include_query = new WP_User_Query( [ 'fields' => [ 'ID', 'display_name' ], 'include' => $include_ids, 'number' => count( $include_ids ), ] ); $include_users = $include_query->get_results(); foreach ( $include_users as $user ) { $results_map[ $user->ID ] = $user; } } $search_args = [ 'number' => 20, 'fields' => [ 'ID', 'display_name' ], 'exclude' => $include_ids, ]; if ( ! empty( $search ) ) { // WP_User_Query escapes the term itself. $search_args['search'] = '*' . $search . '*'; $search_args['search_columns'] = $this->user_search_columns(); } else { $search_args['orderby'] = 'display_name'; $search_args['order'] = 'ASC'; } $search_query = new WP_User_Query( $search_args ); $search_users = $search_query->get_results(); foreach ( $search_users as $user ) { if ( ! isset( $results_map[ $user->ID ] ) ) { $results_map[ $user->ID ] = $user; } } $formatted_options = []; foreach ( $results_map as $user ) { $formatted_options[] = [ 'value' => (string) $user->ID, 'label' => $user->display_name, ]; } return $formatted_options; } /** * Columns the user search may match; e-mail only for users allowed to list users. * * @return string[] */ private function user_search_columns(): array { $columns = [ 'user_login', 'user_nicename', 'display_name' ]; if ( current_user_can( 'list_users' ) ) { $columns[] = 'user_email'; } return $columns; } }