Headline
CVE-2023-5292: module-form-front.php in acf-extended/tags/0.8.9.4/includes/modules/form – WordPress Plugin Repository
The Advanced Custom Fields: Extended plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the ‘acfe_form’ shortcode in versions up to, and including, 0.8.9.3 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers with contributor-level and above permissions to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
1<?php23if(!defined(‘ABSPATH’)){4 exit;5}67if(!class_exists(‘acfe_form_front’)):89class acfe_form_front{10 11 var $fields = array();12 13 function __construct(){14 15 // vars16 $this->fields = array(17 ‘_validate_email’ => array(18 ‘prefix’ => 'acf’,19 ‘name’ => '_validate_email’,20 ‘key’ => '_validate_email’,21 ‘label’ => __('Validate Email’, ‘acf’),22 ‘type’ => 'text’,23 ‘value’ => '’,24 ‘wrapper’ => array(‘style’ => ‘display:none !important;’)25 )26 );27 28 // shortcode29 add_shortcode('acfe_form’, array($this, ‘render_shortcode’));30 31 // save32 add_action('acf/validate_save_post’, array($this, ‘validate_save_post’), 1);33 add_action('wp’, array($this, ‘save_post’));34 35 // ajax36 add_action('wp_ajax_acfe/form/shortcode’, array($this, ‘ajax_shortcode’), 20);37 add_action('wp_ajax_nopriv_acfe/form/shortcode’, array($this, ‘ajax_shortcode’), 20);38 39 }40 41 function ajax_shortcode(){42 43 // validate44 if(!acf_verify_ajax()) die;45 46 // vars47 $args = acf_maybe_get_POST('args’, array());48 $title = '’;49 50 // loop thru args51 foreach(array('name’, ‘id’) as $key){52 53 if(!acf_maybe_get($args, $key)) continue;54 55 $title = acf_maybe_get($args, $key);56 break;57 58 }59 60 $title = is_numeric($title) ? “#{$title}” : "\"{$title}\"";61 62 ob_start();63 ?>64 <div style="border:1px solid #ddd; padding:100px 25px; background:#f8f8f8; text-align:center;">65 <?php _e('Form’, ‘acfe’); ?> <?php echo $title; ?>66 </div>67 <?php echo ob_get_clean();68 die;69 70 }71 72 function validate_save_post(){73 74 // validate front-end75 if(!acfe_is_front()){76 return;77 }78 79 // validate screen80 if(acf_maybe_get_POST(‘_acf_screen’) !== ‘acfe_form’){81 return;82 }83 84 // decrypt85 if(!$form = acfe_form_decrypt_args()){86 return;87 }88 89 $post_id = acf_maybe_get($form, 'post_id’, false);90 $form_name = acf_maybe_get($form, ‘name’);91 $form_id = acf_maybe_get($form, ‘ID’);92 93 // bail early not valid form94 if(!$form_name || !$form_id){95 return;96 }97 98 // local fields99 foreach($this->fields as $k => $field){100 101 // bail early if no in $_POST102 if(!isset($_POST[‘acf’][ $k ])) continue;103 104 // register105 acf_add_local_field($field);106 107 }108 109 // honeypot110 if(!empty($acf[‘_validate_email’])){111 acf_add_validation_error('’, __('Spam Detected’, ‘acf’));112 }113 114 // set form data for validation115 acf_set_form_data('acfe/form’, $form);116 117 // setup meta118 acfe_setup_meta($_POST[‘acf’], 'acfe/form/validation’, true);119 120 // loop121 if(have_rows('acfe_form_actions’, $form_id)):122 while(have_rows('acfe_form_actions’, $form_id)): the_row();123 124 // vars125 $action = get_row_layout();126 $alias = get_sub_field(‘acfe_form_custom_alias’);127 128 // custom action129 if($action === ‘custom’){130 $action = get_sub_field(‘acfe_form_custom_action’);131 $alias = '’;132 }133 134 // actions135 do_action("acfe/form/validation/{$action}", $form, $post_id, $alias);136 do_action("acfe/form/validation/{$action}/form={$form_name}", $form, $post_id, $alias);137 138 if(!empty($alias)){139 do_action("acfe/form/validation/{$action}/action={$alias}", $form, $post_id, $alias);140 }141 142 endwhile;143 endif;144 145 // actions146 do_action("acfe/form/validation", $form, $post_id);147 do_action("acfe/form/validation/form={$form_name}", $form, $post_id);148 149 // reset150 acfe_reset_meta();151 152 // unset form data153 acf_set_form_data('acfe/form’, null);154 155 }156 157 function save_post(){158 159 // verify nonce160 if(!acf_verify_nonce(‘acfe_form’)){161 return;162 }163 164 // decrypt165 if(!$form = acfe_form_decrypt_args()){166 return;167 }168 169 // ACF170 $_POST[‘acf’] = acf_maybe_get_POST('acf’, array());171 172 // run kses on all $_POST data173 if($form[‘kses’]){174 $_POST[‘acf’] = wp_kses_post_deep($_POST[‘acf’]);175 }176 177 // validate save post178 acf_validate_save_post(true);179 180 // vars181 $post_id = acf_maybe_get($form, 'post_id’, false);182 $form_name = acf_maybe_get($form, ‘name’);183 $form_id = acf_maybe_get($form, ‘ID’);184 185 // remove save post action186 add_filter('acf/pre_update_value’, '__return_false’, 99);187 188 // upload files but do not save post189 acf_save_post(false);190 191 // restore save post action192 remove_filter('acf/pre_update_value’, '__return_false’, 99);193 194 // unset files to avoid duplicate upload195 unset($_FILES);196 197 // remove shortcode (temp)198 // https://github.com/elementor/elementor/issues/10998199 // https://github.com/Yoast/wordpress-seo/issues/14643200 remove_shortcode(‘acfe_form’);201 202 // setup meta203 acfe_setup_meta($_POST[‘acf’], 'acfe/form/submit’, true);204 205 // loop206 if(have_rows('acfe_form_actions’, $form_id)):207 208 while(have_rows('acfe_form_actions’, $form_id)): the_row();209 210 // vars211 $action = get_row_layout();212 $alias = get_sub_field(‘acfe_form_custom_alias’);213 214 // action215 do_action("acfe/form/make/{$action}", $form, $post_id, $alias);216 217 endwhile;218 endif;219 220 // actions221 do_action("acfe/form/submit", $form, $post_id);222 do_action("acfe/form/submit/form={$form_name}", $form, $post_id);223 224 // reset225 acfe_reset_meta();226 227 // re-add shortcode228 add_shortcode('acfe_form’, array($this, ‘render_shortcode’));229 230 // return (deprecated)231 if($return = acf_maybe_get($form, 'return’, ‘’)){232 233 // notice234 _deprecated_function('ACF Extended - Dynamic Forms: “Redirection” setting’, '0.8.7.5’, "the new Redirect Action (See documentation: https://www.acf-extended.com/features/modules/dynamic-forms)");235 236 // map values237 $return = acfe_form_map_field_value($return, $post_id, $form);238 239 // redirect240 wp_redirect($return);241 exit;242 243 }244 245 }246 247 function validate_form($param){248 249 // get form250 $array = $this->get_form($param);251 252 // bail early253 if(!$array){254 return false;255 }256 257 // vars258 $form_id = $array[‘ID’];259 $form_name = $array[‘name’];260 261 // filters262 $register = true;263 $register = apply_filters("acfe/form/register", $register, $form_name, $form_id);264 $register = apply_filters("acfe/form/register/name={$form_name}", $register, $form_name, $form_id);265 $register = apply_filters("acfe/form/register/id={$form_id}", $register, $form_name, $form_id);266 267 if($register === false){268 return false;269 }270 271 // Form Attributes272 $form_attributes = get_field('acfe_form_attributes’, $form_id);273 $fields_attributes = get_field('acfe_form_fields_attributes’, $form_id);274 275 // Defaults276 $defaults = array(277 278 // General279 ‘ID’ => '’,280 ‘name’ => '’,281 ‘title’ => '’,282 283 // Settings284 ‘post_id’ => acf_get_valid_post_id(),285 ‘field_groups’ => get_field('acfe_form_field_groups’, $form_id),286 ‘field_groups_rules’ => get_field('acfe_form_field_groups_rules’, $form_id),287 ‘post_field_groups’ => get_field('acfe_form_post_field_groups’, $form_id), // deprecated288 ‘form’ => get_field('acfe_form_form_element’, $form_id),289 ‘html_before_fields’ => get_field('acfe_form_html_before_fields’, $form_id),290 ‘custom_html_enabled’ => get_field('acfe_form_custom_html_enable’, $form_id),291 ‘custom_html’ => get_field('acfe_form_custom_html’, $form_id),292 ‘html_after_fields’ => get_field('acfe_form_html_after_fields’, $form_id),293 ‘form_submit’ => get_field('acfe_form_form_submit’, $form_id),294 ‘submit_value’ => get_field('acfe_form_submit_value’, $form_id),295 ‘html_submit_button’ => get_field('acfe_form_html_submit_button’, $form_id),296 ‘html_submit_spinner’ => get_field('acfe_form_html_submit_spinner’, $form_id),297 298 // Submission299 ‘hide_error’ => get_field('acfe_form_hide_error’, $form_id),300 ‘hide_unload’ => get_field('acfe_form_hide_unload’, $form_id),301 ‘hide_revalidation’ => get_field('acfe_form_hide_revalidation’, $form_id),302 ‘errors_position’ => get_field('acfe_form_errors_position’, $form_id),303 ‘errors_class’ => get_field('acfe_form_errors_class’, $form_id),304 ‘updated_message’ => get_field('acfe_form_updated_message’, $form_id),305 ‘html_updated_message’ => get_field('acfe_form_html_updated_message’, $form_id),306 ‘updated_hide_form’ => get_field('acfe_form_updated_hide_form’, $form_id),307 ‘return’ => get_field('acfe_form_return’, $form_id), // deprecated308 309 // Advanced310 ‘honeypot’ => get_field('acfe_form_honeypot’, $form_id),311 ‘kses’ => get_field('acfe_form_kses’, $form_id),312 ‘uploader’ => get_field('acfe_form_uploader’, $form_id),313 ‘field_el’ => get_field('acfe_form_form_field_el’, $form_id),314 ‘label_placement’ => get_field('acfe_form_label_placement’, $form_id),315 ‘instruction_placement’ => get_field('acfe_form_instruction_placement’, $form_id),316317 // Mapping318 ‘map’ => array(),319 320 // Form Attributes321 ‘form_attributes’ => array(322 ‘id’ => acf_maybe_get($form_attributes, ‘acfe_form_attributes_id’),323 ‘class’ => acf_maybe_get($form_attributes, ‘acfe_form_attributes_class’),324 ‘action’ => '’,325 ‘method’ => 'post’,326 ‘data-fields-class’ => '’,327 ‘data-hide-error’ => '’,328 ‘data-hide-unload’ => '’,329 'data-hide-revalidation’=> '’,330 ‘data-errors-position’ => '’,331 ‘data-errors-class’ => '’,332 ),333 334 // Fields Attributes335 ‘fields_attributes’ => array(336 ‘wrapper_class’ => acf_maybe_get($fields_attributes, ‘acfe_form_fields_wrapper_class’),337 ‘class’ => acf_maybe_get($fields_attributes, ‘acfe_form_fields_class’),338 ),339 340 );341 342 // parse args343 $args = wp_parse_args($array, $defaults);344 345 if(acf_maybe_get($array, ‘form_attributes’)){346 $args[‘form_attributes’] = wp_parse_args($array[‘form_attributes’], $defaults[‘form_attributes’]);347 }348 349 if(acf_maybe_get($array, ‘fields_attributes’)){350 $args[‘fields_attributes’] = wp_parse_args($array[‘fields_attributes’], $defaults[‘fields_attributes’]);351 }352 353 // advanced override354 $args[‘form_attributes’][‘class’] = 'acfe-form ' . $args[‘form_attributes’][‘class’];355 $args[‘form_attributes’][‘data-fields-class’] = $args[‘fields_attributes’][‘class’];356 $args[‘form_attributes’][‘data-hide-error’] = $args[‘hide_error’];357 $args[‘form_attributes’][‘data-hide-unload’] = $args[‘hide_unload’];358 $args[‘form_attributes’][‘data-hide-revalidation’] = $args[‘hide_revalidation’];359 $args[‘form_attributes’][‘data-errors-position’] = $args[‘errors_position’];360 $args[‘form_attributes’][‘data-errors-class’] = $args[‘errors_class’];361 362 if(acf_maybe_get_POST(‘acf’)){363 acfe_setup_meta($_POST[‘acf’], 'acfe/form/load’, true);364 }365 366 // post id367 $post_id = $args[‘post_id’];368 369 // arguments370 $args = apply_filters("acfe/form/load", $args, $post_id);371 $args = apply_filters("acfe/form/load/form={$form_name}", $args, $post_id);372 373 // Load374 if(have_rows('acfe_form_actions’, $form_id)):375 while(have_rows('acfe_form_actions’, $form_id)): the_row();376 377 $action = get_row_layout();378 $alias = get_sub_field(‘acfe_form_custom_alias’);379 380 // Custom Action381 if($action === ‘custom’){382 383 $action = get_sub_field(‘acfe_form_custom_action’);384 $alias = '’;385 386 }387 388 $args = apply_filters("acfe/form/load/{$action}", $args, $post_id, $alias);389 $args = apply_filters("acfe/form/load/{$action}/form={$form_name}", $args, $post_id, $alias);390 391 if(!empty($alias)){392 $args = apply_filters("acfe/form/load/{$action}/action={$alias}", $args, $post_id, $alias);393 }394 395 endwhile;396 endif;397 398 if(acf_maybe_get_POST(‘acf’)){399 acfe_reset_meta();400 }401 402 return $args;403 404 }405 406 /*407 * ACFE Form: render_form408 *409 */410 function render_form($args = array()){411 412 // bail early if no args413 if(!$args = $this->validate_form($args)){414 return;415 }416 417 // success message418 $this->form_success($args);419 420 // enqueue acf421 acf_enqueue_scripts();422 423 // hide form on success424 if($this->form_success_hide($args)){425 return;426 }427 428 $fields = $this->prepare_fields($args);429 430 $this->form_uploader($args);431 432 do_action("acfe/form/render/before_form", $args);433 do_action("acfe/form/render/before_form/id={$args[‘ID’]}", $args);434 do_action("acfe/form/render/before_form/name={$args[‘name’]}", $args);435 436 $this->form_wrapper($args);437438 do_action("acfe/form/render/before_fields", $args);439 do_action("acfe/form/render/before_fields/id={$args[‘ID’]}", $args);440 do_action("acfe/form/render/before_fields/name={$args[‘name’]}",$args);441 442 $this->form_data($args);443 444 $this->fields_wrapper($args);445 446 $this->render_fields($args, $fields);447 448 $this->fields_wrapper($args, false);449 450 do_action("acfe/form/render/after_fields", $args);451 do_action("acfe/form/render/after_fields/id={$args[‘ID’]}", $args);452 do_action("acfe/form/render/after_fields/name={$args[‘name’]}", $args);453 454 $this->form_wrapper($args, false);455 456 do_action("acfe/form/render/after_form", $args);457 do_action("acfe/form/render/after_form/id={$args[‘ID’]}", $args);458 do_action("acfe/form/render/after_form/name={$args[‘name’]}", $args);459 460 }461 462 function form_success($args){463 464 // validate465 if(!acfe_is_form_success($args[‘name’])) return;466 467 // hooks468 do_action("acfe/form/success", $args);469 do_action("acfe/form/success/id={$args[‘ID’]}", $args);470 do_action("acfe/form/success/name={$args[‘name’]}", $args);471 472 // add javascript success473 add_filter('acfe/localize_data’, function($data) use($args){474 475 $data[‘acfe_form_success’][] = array(476 ‘name’ => $args[‘name’],477 ‘id’ => $args[‘ID’],478 );479 480 return $data;481 482 });483 484 // get updated message485 $message = $args[‘updated_message’];486 487 // on success message488 if($message){489 490 // map message with values in $_POST491 if(acf_maybe_get_POST(‘acf’)){492 $message = acfe_form_map_field_value($message, $args[‘post_id’], $args);493 }494 495 // html496 if($args[‘html_updated_message’]){497 $message = sprintf($args[‘html_updated_message’], wp_unslash($message));498 }499 500 // echo501 echo $message;502 503 }504 505 }506 507 function form_success_hide($args){508 509 // hide form on success510 if(acfe_is_form_success($args[‘name’]) && $args[‘updated_hide_form’]){511 return true;512 }513 514 // show515 return false;516 517 }518 519 function prepare_fields($args){520 521 // vars522 $fields = array();523 524 // register local fields525 foreach($this->fields as $field){526 acf_add_local_field($field);527 }528 529 // honeypot530 if($args[‘honeypot’]){531 $fields[] = acf_get_field(‘_validate_email’);532 }533 534 // field attributes535 if($args[‘fields_attributes’][‘wrapper_class’] || $args[‘fields_attributes’][‘class’] || $args[‘label_placement’] === ‘hidden’){536 537 add_filter('acf/prepare_field’, function($field) use($args){538 539 if(!$field){540 return $field;541 }542 543 if($args[‘fields_attributes’][‘wrapper_class’]){544 $field[‘wrapper’][‘class’] .= ' ' . $args[‘fields_attributes’][‘wrapper_class’];545 }546 547 if($args[‘fields_attributes’][‘class’]){548 $field[‘class’] .= ' ' . $args[‘fields_attributes’][‘class’];549 }550 551 if($args[‘label_placement’] === ‘hidden’){552 $field[‘label’] = false;553 }554 555 return $field;556 557 });558 559 }560 561 // form map values562 foreach($args[‘map’] as $key => $_field){563 564 add_filter("acf/prepare_field/key={$key}", function($field) use($_field){565 566 // hide field567 if(!$field || !$_field){568 return false;569 }570 571 return array_merge($field, $_field);572 573 });574 575 }576 577 return $fields;578 579 }580 581 function form_uploader($args){582 583 // uploader (always set in case of multiple forms on the page)584 acf_disable_filter(‘acfe/form/uploader’);585 586 if($args[‘uploader’] !== ‘default’){587 588 acf_enable_filter(‘acfe/form/uploader’);589 acf_update_setting('uploader’, $args[‘uploader’]);590 591 }592 593 }594 595 function form_wrapper($args, $open = true){596 597 // preview mode598 $is_preview = acfe_is_dynamic_preview();599 600 // remove <form>601 if($is_preview){602 $args[‘form’] = false;603 }604 605 // wrapper606 $wrapper = $args[‘form’] ? ‘form’ : 'div’;607 608 // open609 if($open){610 611 // disabled required + fields names612 if($is_preview){613 add_filter('acf/prepare_field’, array($this, ‘disable_fields’));614 }615 616 $atts = acf_esc_atts($args[‘form_attributes’]);617 618 // <form class="acfe-form">619 echo "<{$wrapper} {$atts}>";620 621 // close622 }else{623 624 // </form>625 echo "</{$wrapper}>";626 627 // re-enable required + fields names628 if($is_preview){629 remove_filter('acf/prepare_field’, array($this, ‘disable_fields’));630 }631 632 }633 634 }635 636 function fields_wrapper($args, $open = true){637 638 // open639 if($open){640 641 $atts = array(642 ‘class’ => 'acf-fields acf-form-fields’643 );644 645 if($args[‘label_placement’] !== ‘hidden’){646 $atts[‘class’] .= " -{$args[‘label_placement’]}";647 }648 649 $atts = acf_esc_atts($atts);650 651 // <div class="acf-fields acf-form-fields">652 echo "<div {$atts}>";653 654 // html before fields655 echo $args[‘html_before_fields’];656 657 // close658 }else{659 660 // html after fields661 echo $args[‘html_after_fields’];662 663 echo '</div>’;664 665 // form submit666 if($args[‘form_submit’]): ?>667 <div class="acf-form-submit">668 669 <?php printf($args[‘html_submit_button’], esc_attr($args[‘submit_value’])); ?>670 <?php echo $args[‘html_submit_spinner’]; ?>671672 </div>673 <?php endif;674 675 }676 677 }678 679 function form_data($args){680 681 // bail early in preview mode682 if(acfe_is_dynamic_preview()) return;683 684 // render form data685 acf_form_data(array(686 ‘screen’ => 'acfe_form’,687 ‘post_id’ => $args[‘post_id’],688 ‘form’ => acf_encrypt(json_encode($args))689 ));690 691 }692 693 function render_fields($args, $fields){694 695 // custom html render696 if($args[‘custom_html_enabled’] && $args[‘custom_html’]){697 698 // render honeypot699 acf_render_fields($fields, false, $args[‘field_el’], $args[‘instruction_placement’]);700 701 // render custom html render702 echo acfe_form_render_fields($args[‘custom_html’], $args[‘post_id’], $args);703 704 return;705 706 }707 708 // vars709 $field_groups = array();710 $args[‘field_groups’] = acf_get_array($args[‘field_groups’]);711 712 // post field groups (deprecated, use apply field groups rules instead)713 if($args[‘post_field_groups’]){714 715 // Override Field Groups716 $post_field_groups = acf_get_field_groups(array(717 ‘post_id’ => $args[‘post_field_groups’]718 ));719 720 // re-assign post field groups721 $args[‘field_groups’] = wp_list_pluck($post_field_groups, ‘key’);722 723 }724 725 // form field groups726 foreach($args[‘field_groups’] as $key){727 728 // validate field group exists729 $field_group = acf_get_field_group($key);730 731 if($field_group){732 $field_groups[] = $field_group;733 }734 735 }736 737 // apply field groups rules738 if($args[‘field_groups_rules’] && $field_groups){739 740 $post_id = get_the_ID();741 742 $location = array(743 ‘post_id’ => $post_id,744 ‘post_type’ => get_post_type($post_id),745 );746 747 $filtered = array();748 749 foreach($field_groups as $field_group){750 751 // Deleted field group752 if(!isset($field_group[‘location’])) continue;753 754 // Force active755 $field_group[‘active’] = true;756 757 // fitler field groups758 if(acf_get_field_group_visibility($field_group, $location)){759 $filtered[] = $field_group;760 }761 762 }763 764 // assign new filtered field groups765 $field_groups = $filtered;766 767 }768 769 // get field groups fields770 foreach($field_groups as $field_group){771 772 $_fields = acf_get_fields($field_group);773 774 foreach(array_keys($_fields) as $i){775 776 $fields[] = acf_extract_var($_fields, $i);777 778 }779 780 }781 782 // render fields783 acf_render_fields($fields, acf_uniqid(‘acfe_form’), $args[‘field_el’], $args[‘instruction_placement’]);784 785 }786 787 function render_shortcode($atts){788 789 // attributes array790 $atts = acf_get_array($atts);791 792 // allow array atts793 foreach(array_keys($atts) as $key){794 795 // sub array compatibility796 foreach(array('form_attributes_’, ‘fields_attributes_’) as $allowed){797 798 // check found allowed799 if(!acfe_starts_with($key, $allowed)) continue;800 801 // explode802 $explode = explode($allowed, $key);803 $sub_key = $explode[1];804 805 // set attributes array806 $atts[ substr($allowed, 0, -1) ][ $sub_key ] = $atts[ $key ];807 unset($atts[ $key ]);808 809 }810 811 }812 813 // render814 ob_start();815 816 acfe_form($atts);817 818 return ob_get_clean();819 820 }821 822 function disable_fields($field){823 824 $field[‘name’] = '’;825 $field[‘required’] = false;826 827 return $field;828 829 }830 831 function get_form($param){832 833 $form_id = false;834 $form_name = false;835 $array = array();836 837 // check array838 if(is_array($param)){839 840 // save params841 $array = $param;842 $param = false;843 844 // check keys845 foreach(array('id’, 'ID’, ‘name’) as $key){846 847 if(!acf_maybe_get($array, $key)) continue;848 849 $param = acf_maybe_get($array, $key);850 break;851 852 }853 854 // key not found855 if(!$param){856 return false;857 }858 859 // unset keys860 unset($array[‘id’]);861 unset($array[‘ID’]);862 unset($array[‘name’]);863 864 }865 866 // check id867 if(is_numeric($param)){868 869 // check post type870 if(get_post_type($param) !== ‘acfe-form’){871 return false;872 }873 874 // vars875 $form_id = $param;876 $form_name = get_field('acfe_form_name’, $form_id);877 878 }879 880 // check name881 elseif(is_string($param)){882 883 if(!$form = get_page_by_path($param, OBJECT, ‘acfe-form’)){884 return false;885 }886 887 // vars888 $form_id = $form->ID;889 $form_name = get_field('acfe_form_name’, $form_id);890 891 }892 893 // bail early894 if(!$form_name || !$form_id){895 return false;896 }897 898 // set default params899 $array[‘ID’] = $form_id;900 $array[‘name’] = $form_name;901 $array[‘title’] = get_the_title($form_id);902 903 return $array;904 905 }906 907}908909acf_new_instance(‘acfe_form_front’);910911endif;912913function acfe_form($args = array()){914 915 acf_get_instance(‘acfe_form_front’)->render_form($args);916 917}