1 <?php
2
3 4 5 6 7
8 class Fieldmanager_Datasource_User extends Fieldmanager_Datasource {
9
10 11 12 13
14 public $query_callback = Null;
15
16 17 18 19
20 public $query_args = array();
21
22 23 24 25 26
27 public $use_ajax = True;
28
29 30 31 32 33
34 public $display_property = 'display_name';
35
36 37 38 39
40 protected $allowed_display_properties = array( 'display_name', 'user_login', 'user_email', 'user_nicename' );
41
42 43 44 45 46
47 public $store_property = 'ID';
48
49 50 51 52
53 protected $allowed_store_properties = array( 'ID', 'user_login', 'user_email', 'user_nicename' );
54
55 56 57 58 59
60 public $capability = 'list_users';
61
62 63 64 65 66
67 public $reciprocal = Null;
68
69 70 71
72 public function __construct( $options = array() ) {
73 parent::__construct( $options );
74
75
76 if ( ! in_array( $this->store_property, $this->allowed_store_properties ) ) {
77 throw new FM_Developer_Exception( sprintf(
78 __( 'Store property %s is invalid. Must be one of %s.', 'fieldmanager' ),
79 $this->store_property,
80 implode( ', ', $this->allowed_store_properties )
81 ) );
82 }
83
84 if ( ! empty( $this->reciprocal ) && 'ID' != $this->store_property ) {
85 throw new FM_Developer_Exception( __( 'You cannot use reciprocal relationships with FM_Datasource_User if store_property is not set to ID.', 'fieldmanager' ) );
86 }
87
88
89 if ( ! in_array( $this->display_property, $this->allowed_display_properties ) ) {
90 throw new FM_Developer_Exception( sprintf(
91 __( 'Display property %s is invalid. Must be one of %s.', 'fieldmanager' ),
92 $this->display_property,
93 implode( ', ', $this->allowed_display_properties )
94 ) );
95 }
96 }
97
98 99 100 101 102
103 public function get_value( $value ) {
104 switch ( $this->store_property ) {
105 case 'ID':
106 $field = 'id';
107 break;
108 case 'user_nicename':
109 $field = 'slug';
110 break;
111 case 'user_email':
112 $field = 'email';
113 break;
114 case 'user_login':
115 $field = 'login';
116 break;
117 }
118
119
120 $value = $this->sanitize_value( $value );
121
122 $user = get_user_by( $field, $value );
123 return $user ? $user->{$this->display_property} : '';
124 }
125
126 127 128 129 130 131
132 public function get_items( $fragment = Null ) {
133 if ( is_callable( $this->query_callback ) ) {
134 return call_user_func( $this->query_callback, $fragment );
135 }
136
137 $default_args = array();
138 $user_args = array_merge( $default_args, $this->query_args );
139 $ret = array();
140
141 if ( $fragment ) {
142 $user_args['search'] = '*' . $fragment . '*';
143 }
144
145 $users = get_users( $user_args );
146 foreach ( $users as $u ) {
147 $ret[ $u->{$this->store_property} ] = $u->{$this->display_property};
148 }
149
150 return $ret;
151 }
152
153 154 155 156 157
158 public function get_ajax_action() {
159 if ( !empty( $this->ajax_action ) ) return $this->ajax_action;
160 $unique_key = json_encode( $this->query_args );
161 $unique_key .= $this->display_property;
162 $unique_key .= (string) $this->query_callback;
163 return 'fm_datasource_post' . crc32( $unique_key );
164 }
165
166 167 168 169 170 171
172 public function presave_alter_values( Fieldmanager_Field $field, $values, $current_values ) {
173 if ( $field->data_type != 'post' || ! $this->reciprocal || 'ID' != $this->store_property ) {
174 return $values;
175 }
176
177 if ( ! empty( $current_values ) ) {
178 foreach ( $current_values as $user_id ) {
179 delete_user_meta( $user_id, $this->reciprocal, $field->data_id );
180 }
181 }
182
183 return $values;
184 }
185
186 187 188 189 190 191
192 public function presave( Fieldmanager_Field $field, $value, $current_value ) {
193 if ( empty( $value ) ) {
194 return;
195 }
196
197 $return_single = False;
198 if ( !is_array( $value ) ) {
199 $return_single = True;
200 $value = array( $value );
201 }
202
203 foreach ( $value as $i => $v ) {
204 $value[$i] = $this->sanitize_value( $v );
205 if( ! current_user_can( $this->capability, $v ) ) {
206 wp_die( esc_html( sprintf( __( 'Tried to refer to user "%s" which current user cannot edit.', 'fieldmanager' ), $v ) ) );
207 }
208 if ( $this->reciprocal && 'ID' == $this->store_property ) {
209 add_user_meta( $v, $this->reciprocal, $field->data_id );
210 }
211 }
212
213 return $return_single ? $value[0] : $value;
214 }
215
216 217 218 219 220
221 public function get_view_link( $value ) {
222 return '';
223 }
224
225 226 227 228 229
230 public function get_edit_link( $value ) {
231 return sprintf(
232 ' <a target="_new" class="fm-autocomplete-edit-link %s" href="%s">%s</a>',
233 empty( $value ) ? 'fm-hidden' : '',
234 empty( $value ) ? '#' : esc_url( get_edit_user_link( $value ) ),
235 esc_html__( 'Edit', 'fieldmanager' )
236 );
237 }
238
239 240 241 242 243
244 protected function sanitize_value( $value ) {
245 switch ( $this->store_property ) {
246 case 'ID':
247 $value = intval( $value );
248 break;
249 case 'user_email':
250 $value = sanitize_email( $value );
251 break;
252 default:
253 $value = sanitize_text_field( $value );
254 break;
255 }
256
257 return $value;
258 }
259 }
260