PluginProbe
Advanced Custom Fields (ACF®) / 4.1.1
Advanced Custom Fields (ACF®) v4.1.1
6.8.9 6.8.8 6.8.7 6.8.6 6.8.5 6.8.4 6.8.3 6.8.2 6.8.1 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9 5.9.0 5.9.1 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 5.9.9 6.0.0 All 230 releases
advanced-custom-fields / core / fields / _functions.php
_functions.php
580 lines 12.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * Field Functions
5 *
6 * @description: The API for all fields
7 * @since: 3.6
8 * @created: 23/01/13
9 */
10
11 class acf_field_functions
12 {
13
14 /*
15 * __construct
16 *
17 * @description:
18 * @since 3.1.8
19 * @created: 23/06/12
20 */
21
22 function __construct()
23 {
24 //value
25 add_filter('acf/load_value', array($this, 'load_value'), 5, 3);
26 add_action('acf/update_value', array($this, 'update_value'), 5, 3);
27 add_action('acf/delete_value', array($this, 'delete_value'), 5, 2);
28 add_action('acf/format_value', array($this, 'format_value'), 5, 3);
29 add_action('acf/format_value_for_api', array($this, 'format_value_for_api'), 5, 3);
30
31
32 // field
33 add_filter('acf/load_field', array($this, 'load_field'), 5, 3);
34 add_action('acf/update_field', array($this, 'update_field'), 5, 2);
35 add_action('acf/delete_field', array($this, 'delete_field'), 5, 2);
36 add_action('acf/create_field', array($this, 'create_field'), 5, 1);
37 add_action('acf/create_field_options', array($this, 'create_field_options'), 5, 1);
38
39
40 // extra
41 add_filter('acf/load_field_defaults', array($this, 'load_field_defaults'), 5, 1);
42 }
43
44
45 /*
46 * load_value
47 *
48 * @description: loads basic value from the db
49 * @since: 3.6
50 * @created: 23/01/13
51 */
52
53 function load_value($value, $post_id, $field)
54 {
55 $cache = wp_cache_get( 'load_value/post_id=' . $post_id . '/name=' . $field['name'], 'acf' );
56 if( $cache )
57 {
58 return $cache;
59 }
60
61
62 // if $post_id is a string, then it is used in the everything fields and can be found in the options table
63 if( is_numeric($post_id) )
64 {
65 $value = get_post_meta( $post_id, $field['name'], false );
66
67 // value is an array, check and assign the real value / default value
68 if( !isset($value[0]) )
69 {
70 if( isset($field['default_value']) )
71 {
72 $value = $field['default_value'];
73 }
74 else
75 {
76 $value = false;
77 }
78 }
79 else
80 {
81 $value = $value[0];
82 }
83
84 }
85 elseif( strpos($post_id, 'user_') !== false )
86 {
87 $post_id = str_replace('user_', '', $post_id);
88
89 $value = get_user_meta( $post_id, $field['name'], false );
90
91 // value is an array, check and assign the real value / default value
92 if( !isset($value[0]) )
93 {
94 if( isset($field['default_value']) )
95 {
96 $value = $field['default_value'];
97 }
98 else
99 {
100 $value = false;
101 }
102 }
103 else
104 {
105 $value = $value[0];
106 }
107 }
108 else
109 {
110 $value = get_option( $post_id . '_' . $field['name'], null );
111
112 if( is_null($value) )
113 {
114 if( isset($field['default_value']) )
115 {
116 $value = $field['default_value'];
117 }
118 else
119 {
120 $value = false;
121 }
122 }
123
124 }
125
126
127 // if value was duplicated, it may now be a serialized string!
128 $value = maybe_unserialize($value);
129
130
131 // apply filters
132 foreach( array('type', 'name', 'key') as $key )
133 {
134 // run filters
135 $value = apply_filters('acf/load_value/' . $key . '=' . $field[ $key ], $value, $post_id, $field); // new filter
136 }
137
138
139 //update cache
140 wp_cache_set( 'load_value/post_id=' . $post_id . '/name=' . $field['name'], $value, 'acf' );
141
142
143 return $value;
144 }
145
146
147 /*
148 * format_value
149 *
150 * @description: uses the basic value and allows the field type to format it
151 * @since: 3.6
152 * @created: 26/01/13
153 */
154
155 function format_value( $value, $post_id, $field )
156 {
157 $value = apply_filters('acf/format_value/type=' . $field['type'], $value, $post_id, $field);
158
159 return $value;
160 }
161
162
163 /*
164 * format_value_for_api
165 *
166 * @description: uses the basic value and allows the field type to format it or the api functions
167 * @since: 3.6
168 * @created: 26/01/13
169 */
170
171 function format_value_for_api( $value, $post_id, $field )
172 {
173 $value = apply_filters('acf/format_value_for_api/type=' . $field['type'], $value, $post_id, $field);
174
175 return $value;
176 }
177
178
179 /*
180 * update_value
181 *
182 * @description: updates a value into the db
183 * @since: 3.6
184 * @created: 23/01/13
185 */
186
187 function update_value( $value, $post_id, $field )
188 {
189 // strip slashes
190 // - not needed? http://support.advancedcustomfields.com/discussion/3168/backslashes-stripped-in-wysiwyg-filed
191 //if( get_magic_quotes_gpc() )
192 //{
193 $value = stripslashes_deep($value);
194 //}
195
196
197 // apply filters
198 foreach( array('type', 'name', 'key') as $key )
199 {
200 // run filters
201 $value = apply_filters('acf/update_value/' . $key . '=' . $field[ $key ], $value, $post_id, $field); // new filter
202 }
203
204
205 // if $post_id is a string, then it is used in the everything fields and can be found in the options table
206 if( is_numeric($post_id) )
207 {
208 // allow ACF to save to revision!
209 update_metadata('post', $post_id, $field['name'], $value );
210 update_metadata('post', $post_id, '_' . $field['name'], $field['key']);
211 }
212 elseif( strpos($post_id, 'user_') !== false )
213 {
214 $user_id = str_replace('user_', '', $post_id);
215 update_metadata('user', $user_id, $field['name'], $value);
216 update_metadata('user', $user_id, '_' . $field['name'], $field['key']);
217 }
218 else
219 {
220 // for some reason, update_option does not use stripslashes_deep.
221 // update_metadata -> http://core.trac.wordpress.org/browser/tags/3.4.2/wp-includes/meta.php#L82: line 101 (does use stripslashes_deep)
222 // update_option -> http://core.trac.wordpress.org/browser/tags/3.5.1/wp-includes/option.php#L0: line 215 (does not use stripslashes_deep)
223 $value = stripslashes_deep($value);
224
225 update_option( $post_id . '_' . $field['name'], $value );
226 update_option( '_' . $post_id . '_' . $field['name'], $field['key'] );
227 }
228
229
230 // update the cache
231 wp_cache_set( 'load_value/post_id=' . $post_id . '/name=' . $field['name'], $value, 'acf' );
232 }
233
234
235 /*
236 * delete_value
237 *
238 * @description: deletes a value from the database
239 * @since: 3.6
240 * @created: 23/01/13
241 */
242
243 function delete_value( $post_id, $key )
244 {
245 // if $post_id is a string, then it is used in the everything fields and can be found in the options table
246 if( is_numeric($post_id) )
247 {
248 delete_post_meta( $post_id, $key );
249 delete_post_meta( $post_id, '_' . $key );
250 }
251 elseif( strpos($post_id, 'user_') !== false )
252 {
253 $post_id = str_replace('user_', '', $post_id);
254 delete_user_meta( $post_id, $key );
255 delete_user_meta( $post_id, '_' . $key );
256 }
257 else
258 {
259 delete_option( $post_id . '_' . $key );
260 delete_option( '_' . $post_id . '_' . $key );
261 }
262
263 wp_cache_delete( 'load_value/post_id=' . $post_id . '/name=' . $key, 'acf' );
264 }
265
266
267 /*
268 * load_field
269 *
270 * @description: loads a field from the database
271 * @since 3.5.1
272 * @created: 14/10/12
273 */
274
275 function load_field( $field, $field_key, $post_id = false )
276 {
277 // load cache
278 if( !$field )
279 {
280 $field = wp_cache_get( 'load_field/key=' . $field_key, 'acf' );
281 }
282
283
284 // load from DB
285 if( !$field )
286 {
287 // vars
288 global $wpdb;
289
290
291 // get field from postmeta
292 $sql = $wpdb->prepare("SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = %s", $field_key);
293
294 if( $post_id )
295 {
296 $sql .= $wpdb->prepare("AND post_id = %d", $post_id);
297 }
298
299 $rows = $wpdb->get_results( $sql, ARRAY_A );
300
301
302
303 // nothing found?
304 if( !empty($rows) )
305 {
306 $row = $rows[0];
307
308
309 /*
310 * WPML compatibility
311 *
312 * If WPML is active, and the $post_id (Field group ID) was not defined,
313 * it is assumed that the load_field functio has been called from the API (front end).
314 * In this case, the field group ID is never known and we can check for the correct translated field group
315 */
316
317 if( defined('ICL_LANGUAGE_CODE') && !$post_id )
318 {
319 $wpml_post_id = icl_object_id($row['post_id'], 'acf', true, ICL_LANGUAGE_CODE);
320
321 foreach( $rows as $r )
322 {
323 if( $r['post_id'] == $wpml_post_id )
324 {
325 // this row is a field from the translated field group
326 $row = $r;
327 }
328 }
329 }
330
331
332 // return field if it is not in a trashed field group
333 if( get_post_status( $row['post_id'] ) != "trash" )
334 {
335 $field = $row['meta_value'];
336 $field = maybe_unserialize( $field );
337 $field = maybe_unserialize( $field ); // run again for WPML
338 }
339 }
340 }
341
342
343 // apply filters
344 $field = apply_filters('acf/load_field_defaults', $field);
345
346
347 // apply filters
348 foreach( array('type', 'name', 'key') as $key )
349 {
350 // run filters
351 $field = apply_filters('acf/load_field/' . $key . '=' . $field[ $key ], $field); // new filter
352 }
353
354
355 // set cache
356 wp_cache_set( 'load_field/key=' . $field_key, $field, 'acf' );
357
358 return $field;
359 }
360
361
362 /*
363 * load_field_defaults
364 *
365 * @description: applies default values to the field after it has been loaded
366 * @since 3.5.1
367 * @created: 14/10/12
368 */
369
370 function load_field_defaults( $field )
371 {
372 // validate $field
373 if( ! $field )
374 {
375 $field = array();
376 }
377
378
379 // defaults
380 $defaults = array(
381 'key' => '',
382 'label' => '',
383 'name' => '',
384 'type' => 'text',
385 'order_no' => 1,
386 'instructions' => '',
387 'required' => 0,
388 'id' => '',
389 'class' => '',
390 'conditional_logic' => array(
391 'status' => 0,
392 'allorany' => 'all',
393 'rules' => 0
394 ),
395 );
396 $field = array_merge($defaults, $field);
397
398
399 // Parse Values
400 $field = apply_filters( 'acf/parse_types', $field );
401
402
403 // class
404 if( !$field['class'] )
405 {
406 $field['class'] = $field['type'];
407 }
408
409
410 // id
411 if( !$field['id'] )
412 {
413 $id = $field['name'];
414 $id = str_replace('][', '_', $id);
415 $id = str_replace('fields[', '', $id);
416 $id = str_replace('[', '-', $id); // location rules (select) does'nt have "fields[" in it
417 $id = str_replace(']', '', $id);
418
419 $field['id'] = 'acf-field-' . $id;
420 }
421
422
423 // return
424 return $field;
425 }
426
427
428 /*
429 * update_field
430 *
431 * @description: updates a field in the database
432 * @since: 3.6
433 * @created: 24/01/13
434 */
435
436 function update_field( $field, $post_id )
437 {
438 // sanitize field name
439 // - http://support.advancedcustomfields.com/discussion/5262/sanitize_title-on-field-name
440 // - issue with camel case! Replaced with JS
441 //$field['name'] = sanitize_title( $field['name'] );
442
443
444 // filters
445 $field = apply_filters('acf/update_field/type=' . $field['type'], $field, $post_id ); // new filter
446
447
448 // save
449 update_post_meta( $post_id, $field['key'], $field );
450 }
451
452
453 /*
454 * delete_field
455 *
456 * @description: deletes a field in the database
457 * @since: 3.6
458 * @created: 24/01/13
459 */
460
461 function delete_field( $post_id, $field_key )
462 {
463 // delete
464 delete_post_meta($post_id, $field_key);
465 }
466
467
468 /*
469 * create_field
470 *
471 * @description: renders a field into a HTML interface
472 * @since: 3.6
473 * @created: 23/01/13
474 */
475
476 function create_field( $field )
477 {
478 // load defaults
479 // if field was loaded from db, these default will already be appield
480 // if field was written by hand, it may be missing keys
481 $field = apply_filters('acf/load_field_defaults', $field);
482
483
484 // create field specific html
485 do_action('acf/create_field/type=' . $field['type'], $field);
486
487
488 // conditional logic
489 // - isset is needed for the edit field group page where fields are created without many parameters
490 if( $field['conditional_logic']['status'] ):
491
492 $join = ' && ';
493 if( $field['conditional_logic']['allorany'] == "any" )
494 {
495 $join = ' || ';
496 }
497
498 ?>
499 <script type="text/javascript">
500 (function($){
501
502 // create the conditional function
503 $(document).live('acf/conditional_logic/<?php echo $field['key']; ?>', function(){
504
505 var field = $('.field_key-<?php echo $field['key']; ?>');
506
507 <?php
508
509 $if = array();
510 foreach( $field['conditional_logic']['rules'] as $rule )
511 {
512 $if[] = 'acf.conditional_logic.calculate({ field : "'. $field['key'] .'", toggle : "' . $rule['field'] . '", operator : "' . $rule['operator'] .'", value : "' . $rule['value'] . '"})' ;
513 }
514
515 ?>
516 if(<?php echo implode( $join, $if ); ?>)
517 {
518 field.removeClass('acf-conditional_logic-hide').addClass('acf-conditional_logic-show');
519 }
520 else
521 {
522 field.removeClass('acf-conditional_logic-show').addClass('acf-conditional_logic-hide');
523 }
524
525 });
526
527
528 // add change events to all fields
529 <?php
530
531 $already_added = array();
532
533 foreach( $field['conditional_logic']['rules'] as $rule ):
534
535 if( in_array( $rule['field'], $already_added) )
536 {
537 continue;
538 }
539 else
540 {
541 $already_added[] = $rule['field'];
542 }
543
544 ?>
545 $('.field_key-<?php echo $rule['field']; ?> *[name]').live('change', function(){
546 $(document).trigger('acf/conditional_logic/<?php echo $field['key']; ?>');
547 });
548 <?php endforeach; ?>
549
550 $(document).live('acf/setup_fields', function(e, postbox){
551 $(document).trigger('acf/conditional_logic/<?php echo $field['key']; ?>');
552 });
553
554 })(jQuery);
555 </script>
556 <?php
557 endif;
558 }
559
560
561 /*
562 * create_field_options
563 *
564 * @description: renders a field into a HTML interface
565 * @since: 3.6
566 * @created: 23/01/13
567 */
568
569 function create_field_options($field)
570 {
571 do_action('acf/create_field_options/type=' . $field['type'], $field);
572 }
573
574
575
576 }
577
578 new acf_field_functions();
579
580 ?>