admin
3 months ago
field-groups
3 months ago
fields
1 week ago
fields-settings
3 months ago
forms
3 months ago
locations
3 months ago
modules
1 week ago
screens
3 months ago
acfe-deprecated-functions.php
2 years ago
acfe-field-functions.php
3 months ago
acfe-field-group-functions.php
3 months ago
acfe-file-functions.php
1 year ago
acfe-form-functions.php
3 months ago
acfe-helper-array-functions.php
3 months ago
acfe-helper-functions.php
3 months ago
acfe-helper-multi-functions.php
3 months ago
acfe-helper-string-functions.php
3 months ago
acfe-meta-functions.php
3 months ago
acfe-post-functions.php
3 months ago
acfe-screen-functions.php
3 months ago
acfe-template-functions.php
3 months ago
acfe-term-functions.php
3 months ago
acfe-user-functions.php
3 months ago
acfe-wp-functions.php
3 years ago
assets.php
3 months ago
compatibility-acf-5.8.php
4 months ago
compatibility-acf-5.9.php
3 months ago
compatibility-acf-6.5.php
3 months ago
compatibility-acf-6.8.6.php
1 week ago
compatibility.php
3 months ago
field-extend.php
4 months ago
field.php
4 months ago
hooks.php
3 months ago
init.php
3 months ago
local-meta.php
3 years ago
media.php
3 months ago
module-acf.php
3 months ago
module-db.php
3 months ago
module-l10n.php
3 months ago
module-legacy.php
3 years ago
module-manager.php
4 months ago
module-post.php
3 months ago
module-posts.php
4 months ago
module-upgrades.php
3 years ago
module.php
3 months ago
multilang.php
3 months ago
revisions.php
4 months ago
screen.php
3 months ago
settings.php
3 months ago
template-tags.php
3 months ago
third-party.php
3 years ago
upgrades.php
3 months ago
acfe-field-functions.php
642 lines
| 1 | <?php |
| 2 | |
| 3 | if(!defined('ABSPATH')){ |
| 4 | exit; |
| 5 | } |
| 6 | |
| 7 | /** |
| 8 | * acfe_get_field_group_from_field |
| 9 | * |
| 10 | * Retrieve the Field Group, starting from any field or sub field |
| 11 | * |
| 12 | * @param $field |
| 13 | * |
| 14 | * @return array|false|mixed|void|null |
| 15 | */ |
| 16 | function acfe_get_field_group_from_field($field){ |
| 17 | |
| 18 | // allow field key or name |
| 19 | if(!is_array($field)){ |
| 20 | $field = acf_get_field($field); |
| 21 | } |
| 22 | |
| 23 | // check parent exists |
| 24 | if(!acfe_get($field, 'parent')){ |
| 25 | return false; |
| 26 | } |
| 27 | |
| 28 | // get parent fields and reverse order (top field first) |
| 29 | $ancestors = acf_get_field_ancestors($field); |
| 30 | $ancestors = array_reverse($ancestors); |
| 31 | |
| 32 | // no ancestors, return field group |
| 33 | if(!$ancestors){ |
| 34 | return acf_get_field_group($field['parent']); |
| 35 | } |
| 36 | |
| 37 | // retrieve top field |
| 38 | $top_field = acf_get_field($ancestors[0]); |
| 39 | |
| 40 | // return |
| 41 | return acf_get_field_group($top_field['parent']); |
| 42 | |
| 43 | } |
| 44 | |
| 45 | /** |
| 46 | * acfe_get_field_descendants |
| 47 | * |
| 48 | * Similar to acf_get_field_ancestors but retrieve all descendants instead |
| 49 | * |
| 50 | * @param $field |
| 51 | * |
| 52 | * @return array |
| 53 | */ |
| 54 | function acfe_get_field_descendants($field){ |
| 55 | |
| 56 | // allow field key or name |
| 57 | if(!is_array($field)){ |
| 58 | $field = acf_get_field($field); |
| 59 | } |
| 60 | |
| 61 | // var |
| 62 | $descendants = array(); |
| 63 | $sub_fields = acf_get_fields($field); |
| 64 | |
| 65 | // no sub fields |
| 66 | if(!$sub_fields){ |
| 67 | return $descendants; |
| 68 | } |
| 69 | |
| 70 | // loop sub fields |
| 71 | foreach($sub_fields as $sub_field){ |
| 72 | |
| 73 | $descendants[] = $sub_field['ID'] ? $sub_field['ID'] : $sub_field['key']; |
| 74 | |
| 75 | if(isset($sub_field['sub_fields'])){ |
| 76 | $descendants = array_merge($descendants, acfe_get_field_descendants($sub_field)); |
| 77 | } |
| 78 | |
| 79 | } |
| 80 | |
| 81 | // return |
| 82 | return $descendants; |
| 83 | |
| 84 | } |
| 85 | |
| 86 | /** |
| 87 | * acfe_extract_sub_field |
| 88 | * |
| 89 | * Extract Sub Field form Layout & Set Value |
| 90 | * |
| 91 | * @param $layout |
| 92 | * @param $name |
| 93 | * @param $value |
| 94 | * |
| 95 | * @return false|mixed |
| 96 | */ |
| 97 | function acfe_extract_sub_field(&$layout, $name, $value){ |
| 98 | |
| 99 | $sub_field = false; |
| 100 | |
| 101 | // loop |
| 102 | foreach($layout['sub_fields'] as $k => $row){ |
| 103 | |
| 104 | if($row['name'] === $name){ |
| 105 | $sub_field = acf_extract_var($layout['sub_fields'], $k); |
| 106 | break; |
| 107 | } |
| 108 | |
| 109 | } |
| 110 | |
| 111 | if(!$sub_field){ |
| 112 | return false; |
| 113 | } |
| 114 | |
| 115 | // reset keys |
| 116 | $layout['sub_fields'] = array_values($layout['sub_fields']); |
| 117 | |
| 118 | // add value |
| 119 | if(isset($value[$sub_field['key']])){ |
| 120 | $sub_field['value'] = $value[$sub_field['key']]; |
| 121 | |
| 122 | }elseif(isset($sub_field['default_value'])){ |
| 123 | $sub_field['value'] = $sub_field['default_value']; |
| 124 | } |
| 125 | |
| 126 | return $sub_field; |
| 127 | |
| 128 | } |
| 129 | |
| 130 | /** |
| 131 | * acfe_map_fields |
| 132 | * |
| 133 | * Map custom callback to all fields and subfields passed |
| 134 | * |
| 135 | * @param $field |
| 136 | * @param $callback |
| 137 | * |
| 138 | * @return mixed |
| 139 | */ |
| 140 | function acfe_map_fields($field, $callback){ |
| 141 | |
| 142 | // bail early |
| 143 | if(empty($field)){ |
| 144 | return $field; |
| 145 | } |
| 146 | |
| 147 | /** |
| 148 | * multiple fields array |
| 149 | * |
| 150 | * array( |
| 151 | * array( |
| 152 | * 'key' => 'field_5c9a1b0b9c2a1', |
| 153 | * 'label' => 'Field 1', |
| 154 | * 'name' => 'field_1', |
| 155 | * 'type' => 'text', |
| 156 | * ), |
| 157 | * array( |
| 158 | * 'key' => 'field_5c9a1b0b9c2a2', |
| 159 | * 'label' => 'Field 2', |
| 160 | * 'name' => 'field_2', |
| 161 | * 'type' => 'text', |
| 162 | * ), |
| 163 | * ) |
| 164 | */ |
| 165 | if(acf_is_sequential_array($field)){ |
| 166 | |
| 167 | $fields = $field; |
| 168 | |
| 169 | foreach(array_keys($fields) as $k){ |
| 170 | $fields[ $k ] = acfe_map_fields($fields[ $k ], $callback); |
| 171 | } |
| 172 | |
| 173 | return $fields; |
| 174 | |
| 175 | } |
| 176 | |
| 177 | /** |
| 178 | * single field array |
| 179 | * |
| 180 | * array( |
| 181 | * 'key' => 'field_5c9a1b0b9c2a1', |
| 182 | * 'label' => 'Field', |
| 183 | * 'name' => 'field', |
| 184 | * 'type' => 'text', |
| 185 | * ) |
| 186 | */ |
| 187 | $field = call_user_func($callback, $field); |
| 188 | |
| 189 | // subfields |
| 190 | // repeater, group... |
| 191 | if(acfe_get($field, 'sub_fields')){ |
| 192 | $field['sub_fields'] = acfe_map_fields($field['sub_fields'], $callback); |
| 193 | } |
| 194 | |
| 195 | // layouts |
| 196 | // flexible content |
| 197 | if(acfe_get($field, 'layouts')){ |
| 198 | |
| 199 | foreach(array_keys($field['layouts']) as $l){ |
| 200 | |
| 201 | if(acfe_get($field['layouts'][ $l ], 'sub_fields')){ |
| 202 | $field['layouts'][ $l ]['sub_fields'] = acfe_map_fields($field['layouts'][ $l ]['sub_fields'], $callback); |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | } |
| 207 | |
| 208 | return $field; |
| 209 | |
| 210 | } |
| 211 | |
| 212 | |
| 213 | /** |
| 214 | * acfe_query_field |
| 215 | * |
| 216 | * @param $args |
| 217 | * |
| 218 | * @return false|mixed |
| 219 | */ |
| 220 | function acfe_query_field($args = array()){ |
| 221 | |
| 222 | // default limit |
| 223 | $args = wp_parse_args($args, array( |
| 224 | 'limit' => 1 |
| 225 | )); |
| 226 | |
| 227 | // query |
| 228 | $fields = acfe_query_fields($args); |
| 229 | |
| 230 | // return |
| 231 | return current($fields); |
| 232 | |
| 233 | } |
| 234 | |
| 235 | |
| 236 | /** |
| 237 | * acfe_query_fields |
| 238 | * |
| 239 | * @param $args |
| 240 | * |
| 241 | * @return array |
| 242 | */ |
| 243 | function acfe_query_fields($args = array()){ |
| 244 | |
| 245 | // vars |
| 246 | $storage = array(); |
| 247 | $fields = array(); |
| 248 | |
| 249 | // validate query |
| 250 | $args = wp_parse_args($args, array( |
| 251 | 'query' => array(), // main query, should be compatible with wp_list_filter() |
| 252 | 'context' => acf_get_field_groups(), // can be field/field group array, or field/field group key, array of fields or field groups etc... |
| 253 | 'orderby' => false, // orderby list |
| 254 | 'order' => 'ASC', // order list |
| 255 | 'limit' => 0, // limit list |
| 256 | 'offset' => 0, // offset list |
| 257 | 'level' => -1, // maximum allowed field level (-1 = any, 0 = only top level, 1 = max 1 sub level etc...) |
| 258 | 'field' => false, // list pluck field |
| 259 | 'filters' => true, // enable/disable acf_filters (such as clone, local) |
| 260 | |
| 261 | // internal args |
| 262 | '_query' => false, |
| 263 | '_depth' => 0, |
| 264 | '_level' => 0, |
| 265 | '_filters' => false, |
| 266 | )); |
| 267 | |
| 268 | // validate context |
| 269 | $args['context'] = acfe_as_array($args['context']); |
| 270 | |
| 271 | // validate query |
| 272 | $args['query'] = acfe_as_array($args['query']); |
| 273 | |
| 274 | // top-level call |
| 275 | if(!$args['_depth']){ |
| 276 | |
| 277 | // disable acf filters |
| 278 | if(!$args['filters']){ |
| 279 | $args['_filters'] = acf_disable_filters(); |
| 280 | } |
| 281 | |
| 282 | } |
| 283 | |
| 284 | // process query |
| 285 | if($args['_query'] === false){ |
| 286 | |
| 287 | $_query = array(); |
| 288 | |
| 289 | /** |
| 290 | * $_query = array('type' => 'text'); |
| 291 | |
| 292 | * $_query = array( |
| 293 | * array('type' => 'text'), |
| 294 | * array('type' => 'image'), |
| 295 | * ); |
| 296 | |
| 297 | * $_query = array( |
| 298 | * 'relation' => 'AND', |
| 299 | * array( |
| 300 | * 'type' => 'text', |
| 301 | * 'name' => 'my_text' |
| 302 | * ) |
| 303 | * ); |
| 304 | |
| 305 | * $_query = array( |
| 306 | * array( |
| 307 | * 'relation' => 'AND', |
| 308 | * array( |
| 309 | * 'type' => 'text', |
| 310 | * 'name' => 'my_text' |
| 311 | * ) |
| 312 | * ), |
| 313 | * array( |
| 314 | * 'relation' => 'AND', |
| 315 | * array( |
| 316 | * 'type' => 'image', |
| 317 | * 'name' => 'my_image' |
| 318 | * ) |
| 319 | * ), |
| 320 | * ); |
| 321 | */ |
| 322 | |
| 323 | /** |
| 324 | * $_query = array( |
| 325 | * array('type' => 'text'), |
| 326 | * array('type' => 'image'), |
| 327 | * ) |
| 328 | */ |
| 329 | if(acf_is_associative_array($args['query'])){ |
| 330 | |
| 331 | if(!isset($args['query']['relation'])){ |
| 332 | |
| 333 | $_query[] = array( |
| 334 | 'relation' => 'AND', |
| 335 | $args['query'] |
| 336 | ); |
| 337 | |
| 338 | }else{ |
| 339 | |
| 340 | if(isset($args['query'][0]) && is_array($args['query'][0])){ |
| 341 | |
| 342 | $_query[] = array( |
| 343 | 'relation' => $args['query']['relation'], |
| 344 | $args['query'][0] |
| 345 | ); |
| 346 | |
| 347 | } |
| 348 | |
| 349 | } |
| 350 | |
| 351 | }else{ |
| 352 | |
| 353 | foreach($args['query'] as $q){ |
| 354 | |
| 355 | if(!isset($q['relation'])){ |
| 356 | |
| 357 | if(isset($q[0]) && is_array($q[0])){ |
| 358 | |
| 359 | if(!empty($q[0])){ |
| 360 | $_query[] = array( |
| 361 | 'relation' => 'AND', |
| 362 | current($q) |
| 363 | ); |
| 364 | } |
| 365 | |
| 366 | }elseif(!empty($q)){ |
| 367 | |
| 368 | $_query[] = array( |
| 369 | 'relation' => 'AND', |
| 370 | $q |
| 371 | ); |
| 372 | |
| 373 | } |
| 374 | |
| 375 | }else{ |
| 376 | |
| 377 | if(isset($q[0]) && is_array($q[0]) && !empty($q[0])){ |
| 378 | |
| 379 | $_query[] = array( |
| 380 | 'relation' => $q['relation'], |
| 381 | $q[0] |
| 382 | ); |
| 383 | |
| 384 | } |
| 385 | |
| 386 | } |
| 387 | |
| 388 | } |
| 389 | |
| 390 | } |
| 391 | |
| 392 | // empty query = all |
| 393 | if(empty($_query)){ |
| 394 | |
| 395 | $_query[] = array( |
| 396 | 'relation' => 'AND', |
| 397 | array() |
| 398 | ); |
| 399 | |
| 400 | } |
| 401 | |
| 402 | // assign |
| 403 | $args['_query'] = $_query; |
| 404 | |
| 405 | } |
| 406 | |
| 407 | // $field |
| 408 | // $field_group |
| 409 | if(acf_is_associative_array($args['context'])){ |
| 410 | |
| 411 | // field group |
| 412 | if(acf_is_field_group($args['context'])){ |
| 413 | $fields = acf_get_fields($args['context']); |
| 414 | |
| 415 | // field |
| 416 | }else{ |
| 417 | |
| 418 | foreach($args['_query'] as $q){ |
| 419 | $storage = array_merge($storage, wp_list_filter(array($args['context']), $q[0], $q['relation'])); |
| 420 | } |
| 421 | |
| 422 | // query sub fields |
| 423 | if(!empty($args['context']['sub_fields'])){ |
| 424 | $args['_level']++; |
| 425 | $fields = $args['context']['sub_fields']; |
| 426 | } |
| 427 | |
| 428 | } |
| 429 | |
| 430 | if($fields){ |
| 431 | foreach($fields as $field){ |
| 432 | |
| 433 | foreach($args['_query'] as $q){ |
| 434 | $storage = array_merge($storage, wp_list_filter(array($field), $q[0], $q['relation'])); |
| 435 | } |
| 436 | |
| 437 | // query sub fields |
| 438 | if(isset($field['sub_fields'])){ |
| 439 | |
| 440 | if($args['level'] === -1 || ($args['level'] > 0 && $args['_level'] < $args['level'])){ |
| 441 | |
| 442 | // sub query |
| 443 | $_args = $args; |
| 444 | $_args['context'] = $field; |
| 445 | $_args['_depth']++; |
| 446 | |
| 447 | $storage = array_merge($storage, acfe_query_fields($_args)); |
| 448 | |
| 449 | } |
| 450 | |
| 451 | } |
| 452 | |
| 453 | } |
| 454 | } |
| 455 | |
| 456 | // array(field_abcdef123456, field_abcdef123456) |
| 457 | // array(group_abcdef123456, group_abcdef123456) |
| 458 | // array($field, $field) |
| 459 | // array($field_group, $field_group) |
| 460 | }else{ |
| 461 | |
| 462 | foreach($args['context'] as $context){ |
| 463 | |
| 464 | // set new sub context |
| 465 | $_args = $args; |
| 466 | $_args['_depth']++; |
| 467 | |
| 468 | // array |
| 469 | if(is_array($context)){ |
| 470 | |
| 471 | $_args['context'] = $context; |
| 472 | |
| 473 | // numeric |
| 474 | }elseif(is_numeric($context)){ |
| 475 | |
| 476 | $post_type = get_post_type($context); |
| 477 | |
| 478 | if($post_type === 'acf-field-group'){ |
| 479 | $_args['context'] = acf_get_field_group($context); |
| 480 | |
| 481 | }elseif($post_type === 'acf-field'){ |
| 482 | $_args['context'] = acf_get_field($context); |
| 483 | } |
| 484 | |
| 485 | // string |
| 486 | }else{ |
| 487 | |
| 488 | // group_abcdef123456 |
| 489 | if(acf_is_field_group_key($context)){ |
| 490 | $_args['context'] = acf_get_fields($context); |
| 491 | |
| 492 | // field_abcdef123456 |
| 493 | }else{ |
| 494 | $_args['context'] = acf_get_field($context); |
| 495 | } |
| 496 | |
| 497 | } |
| 498 | |
| 499 | // loop query |
| 500 | $storage = array_merge($storage, acfe_query_fields($_args)); |
| 501 | |
| 502 | } |
| 503 | |
| 504 | } |
| 505 | |
| 506 | // unique array |
| 507 | // make sure returned fields are unique (based on field key) |
| 508 | $temp = array(); |
| 509 | $storage = array_filter($storage, function($field) use(&$temp){ |
| 510 | if(in_array($field['key'], $temp)){ |
| 511 | return false; |
| 512 | }else{ |
| 513 | $temp[] = $field['key']; |
| 514 | return true; |
| 515 | } |
| 516 | }); |
| 517 | |
| 518 | // reorder |
| 519 | $storage = array_values($storage); |
| 520 | |
| 521 | // top-level call |
| 522 | if(!$args['_depth']){ |
| 523 | |
| 524 | // order |
| 525 | if($args['orderby']){ |
| 526 | $args['order'] = $args['order'] === 'ASC' ? 'ASC' : 'DESC'; |
| 527 | $storage = wp_list_sort($storage, $args['orderby'], $args['order']); |
| 528 | } |
| 529 | |
| 530 | // field |
| 531 | if($args['field']){ |
| 532 | $storage = wp_list_pluck($storage, $args['field']); |
| 533 | } |
| 534 | |
| 535 | // offset |
| 536 | if($args['offset'] > 0){ |
| 537 | $storage = array_slice($storage, $args['offset']); |
| 538 | } |
| 539 | |
| 540 | // limit |
| 541 | if($args['limit'] > 0){ |
| 542 | $storage = array_slice($storage, 0, $args['limit']); |
| 543 | } |
| 544 | |
| 545 | // re-enable acf filters |
| 546 | if(!$args['filters']){ |
| 547 | acf_enable_filters($args['_filters']); |
| 548 | } |
| 549 | |
| 550 | } |
| 551 | |
| 552 | // return |
| 553 | return $storage; |
| 554 | |
| 555 | } |
| 556 | |
| 557 | /** |
| 558 | * acfe_get_fields_details_recursive |
| 559 | * |
| 560 | * @param $fields |
| 561 | * |
| 562 | * @return array|mixed |
| 563 | */ |
| 564 | function acfe_get_fields_details_recursive($fields, $callback = false){ |
| 565 | |
| 566 | $fields = acfe_as_array($fields); |
| 567 | $return = array(); |
| 568 | |
| 569 | foreach($fields as $field){ |
| 570 | |
| 571 | // check callback |
| 572 | if($callback && is_callable($callback)){ |
| 573 | |
| 574 | // execute callback |
| 575 | $field = call_user_func($callback, $field); |
| 576 | |
| 577 | // allow to return false to bypass field |
| 578 | if(!$field){ |
| 579 | continue; |
| 580 | } |
| 581 | |
| 582 | } |
| 583 | |
| 584 | // pass clone subfields parent as field key (instead of field group) |
| 585 | if($field['type'] === 'clone'){ |
| 586 | if(acfe_get($field, 'sub_fields')){ |
| 587 | foreach($field['sub_fields'] as &$sub_field){ |
| 588 | $sub_field['parent'] = $field['key']; |
| 589 | } |
| 590 | } |
| 591 | } |
| 592 | |
| 593 | $ancestors = isset($field['ancestors']) ? $field['ancestors'] : count(acf_get_field_ancestors($field)); |
| 594 | |
| 595 | $label = ''; |
| 596 | $label = str_repeat('- ', $ancestors) . $label; |
| 597 | $label .= !empty($field['label']) ? $field['label'] : '(' . __('no label', 'acf') . ')'; |
| 598 | $label .= $field['required'] ? ' <span class="acf-required">*</span>' : ''; |
| 599 | |
| 600 | $field_type = acf_get_field_type($field['type']); |
| 601 | $type = isset($field_type->label) ? $field_type->label : '-'; |
| 602 | |
| 603 | $return[] = array( |
| 604 | 'label' => $label, |
| 605 | 'name' => $field['name'], |
| 606 | 'key' => $field['key'], |
| 607 | 'type' => $type, |
| 608 | 'field' => $field, |
| 609 | ); |
| 610 | |
| 611 | if(acfe_get($field, 'sub_fields')){ |
| 612 | $return = array_merge($return, acfe_get_fields_details_recursive($field['sub_fields'], $callback)); |
| 613 | } |
| 614 | |
| 615 | } |
| 616 | |
| 617 | return $return; |
| 618 | |
| 619 | } |
| 620 | |
| 621 | |
| 622 | /** |
| 623 | * acfe_get_pretty_field_label |
| 624 | * |
| 625 | * @param $field |
| 626 | * @param $with_key |
| 627 | * |
| 628 | * @return mixed|string|null |
| 629 | */ |
| 630 | function acfe_get_pretty_field_label($field, $with_key = false){ |
| 631 | |
| 632 | // vars |
| 633 | $name = isset($field['_name']) ? $field['_name'] : $field['name']; |
| 634 | $label = acfe_get($field, 'label', $name); |
| 635 | |
| 636 | if($with_key){ |
| 637 | $label .= " ({$field['key']})"; |
| 638 | } |
| 639 | |
| 640 | return $label; |
| 641 | |
| 642 | } |