web/wp-content/plugins/acf-extended/includes/modules/form/module-form-front.php (303 lines of code) (raw):

<?php if(!defined('ABSPATH')){ exit; } if(!class_exists('acfe_module_form_front')): class acfe_module_form_front{ /** * construct */ function __construct(){ add_action('acf/validate_save_post', array($this, 'validate_save_post'), 1); add_action('wp', array($this, 'save_post')); add_action('acfe/form/validate_form', array($this, 'validate_form'), 9); add_action('acfe/form/submit_form', array($this, 'submit_form'), 9); add_filter('acfe/form/load_form', array($this, 'load_form'), 19); add_filter('acfe/form/set_form_data', array($this, 'set_form_data'), 10, 2); add_action( 'wp_ajax_acfe/form/render_form_ajax', array($this, 'render_form_ajax')); add_action('wp_ajax_nopriv_acfe/form/render_form_ajax', array($this, 'render_form_ajax')); } /** * validate_form * * @param $form * * @return void */ function validate_form($form){ add_action("acfe/form/validate_form/form={$form['name']}", array($this, 'validate_actions'), 9); do_action("acfe/form/validate_form/form={$form['name']}", $form); } /** * submit_form * * @param $form * * @return void */ function submit_form($form){ add_action("acfe/form/submit_form/form={$form['name']}", array($this, 'submit_actions'), 9); do_action("acfe/form/submit_form/form={$form['name']}", $form); } /** * load_form * * @param $form * * @return false|mixed|null */ function load_form($form){ if(!$form){ return false; } // load actions add_filter("acfe/form/load_form/form={$form['name']}", array($this, 'load_actions'), 19); return apply_filters("acfe/form/load_form/form={$form['name']}", $form); } /** * validate_save_post * * acf/validate_save_post:1 */ function validate_save_post(){ // get form $form = $this->get_form_validation(); // bail early if(!$form){ return; } // set form data // used in validation with acfe_add_validation_error() acf_set_form_data('acfe/form', $form); // tags context acfe_add_context('form', $form); acfe_add_context('method', 'validate'); // setup meta acfe_setup_meta(wp_unslash($_POST['acf']), 'acfe/form/validation', true); // validate form do_action("acfe/form/validate_form", $form); // reset acfe_reset_meta(); } /** * validate_actions * * @param $form * * @return void */ function validate_actions($form){ // force array $form['actions'] = acf_get_array($form['actions']); // validate actions foreach($form['actions'] as $action){ // tags context acfe_add_context('action', $action); // validate action do_action("acfe/form/validate_{$action['action']}", $form, $action); do_action("acfe/form/validate_{$action['action']}/form={$form['name']}", $form, $action); do_action("acfe/form/validate_{$action['action']}/action={$action['name']}", $form, $action); // tags context acfe_delete_context('action'); } } /** * save_post * * wp */ function save_post(){ // get form $form = $this->get_form_submission(); // bail early if(!$form){ return; } // default acf if(empty($_POST['acf'])){ $_POST['acf'] = array(); } // default acf // this pass thru acf_sanitize_request_args() which use wp_kses // and break block editor image metadata // $_POST['acf'] = acf_maybe_get_POST('acf', array()); // run kses on all $_POST data if($form['settings']['kses']){ // wp_kses_post_deep() expects unslashed data $_POST['acf'] = wp_kses_post_deep(wp_unslash($_POST['acf'])); $_POST['acf'] = wp_slash($_POST['acf']); // slash data back } // should we show errors and die $show_errors = true; $show_errors = apply_filters("acfe/form/submit_show_errors", $show_errors, $form); $show_errors = apply_filters("acfe/form/submit_show_errors/form={$form['name']}", $show_errors, $form); // validate save post // pass thru $this->validate_save_post() $valid = acf_validate_save_post($show_errors); // invalid form if(!$valid){ return; } // set form data acf_set_form_data('acfe/form', $form); // tags context acfe_add_context('form', $form); acfe_add_context('method', 'submit'); // remove save post action add_filter('acf/pre_update_value', '__return_false', 99); // upload files but do not save post acf_save_post(false); // restore save post action remove_filter('acf/pre_update_value', '__return_false', 99); // unset files to avoid duplicate upload unset($_FILES); // remove shortcode temporarly // https://github.com/elementor/elementor/issues/10998 // https://github.com/Yoast/wordpress-seo/issues/14643 remove_shortcode('acfe_form'); // setup meta acfe_setup_meta(wp_unslash($_POST['acf']), 'acfe/form/submit', true); // submit form do_action("acfe/form/submit_form", $form); // submit_success do_action("acfe/form/submit_success", $form); do_action("acfe/form/submit_success/form={$form['name']}", $form); // reset acfe_reset_meta(); // re-add shortcode add_shortcode('acfe_form', array(acf_get_instance('acfe_module_form_shortcode'), 'render_shortcode')); // prevent refresh add_action('wp_print_footer_scripts', array($this, 'prevent_refresh')); // return (deprecated) if($return = acf_maybe_get($form, 'return')){ acfe_redirect($return); } } /** * submit_actions * * @param $form * * @return void */ function submit_actions($form){ // force array $form['actions'] = acf_get_array($form['actions']); // submit actions foreach($form['actions'] as $action){ // tags context acfe_add_context('action', $action); // prepare action $action = apply_filters("acfe/form/prepare_{$action['action']}", $action, $form); if($action){$action = apply_filters("acfe/form/prepare_{$action['action']}/form={$form['name']}", $action, $form);} if($action){$action = apply_filters("acfe/form/prepare_{$action['action']}/action={$action['name']}", $action, $form);} if($action === false){ continue; } // make action do_action("acfe/form/make_{$action['action']}", $form, $action); // tags context acfe_delete_context('action'); } } /** * get_form * * @param $form * * @return array|mixed */ function get_form($form){ // allow non array argument if(!is_array($form)){ $arg = $form; $form = array( 'ID' => is_numeric($arg) ? $arg : 0, 'name' => !is_numeric($arg) ? $arg : '', ); } // check lowercase id if(isset($form['id'])){ $form['ID'] = acf_extract_var($form, 'id'); } // get module $module = acfe_get_module('form'); // get by name or ID $selector = !empty($form['name']) ? $form['name'] : acf_maybe_get($form, 'ID'); if($selector){ // get item $item = $module->get_item($selector); // merge arrays if($item){ // assign item vars $form['ID'] = $item['ID']; $form['name'] = $item['name']; $form = acfe_parse_args_r($form, $item); // allow validate_item again acf_extract_vars($form, array('_valid')); } } // validate form (set alias) // also add settings in case there is no form found $form = $module->validate_item($form); // cleanup keys acf_extract_vars($form, array('label', 'modified', 'local', 'local_file', '_valid')); // add post id if(!isset($form['post_id'])){ $form['post_id'] = acfe_get_post_id(); } // add uniqid if(!isset($form['uniqid'])){ $form['uniqid'] = acf_uniqid("acfe_form_{$form['name']}"); } // add cid (visible in the DOM) if(!isset($form['cid'])){ $form['cid'] = uniqid(); } // add map if(!isset($form['map'])){ $form['map'] = array(); } return $form; } /** * load_actions * * @param $form * * @return mixed|null */ function load_actions($form){ if(!$form){ return false; } // update context acfe_add_context('form', $form); // tags context $opt = array('context' => 'display'); // apply tags acfe_apply_tags($form['attributes']['form']['class'], $opt); acfe_apply_tags($form['attributes']['form']['id'], $opt); acfe_apply_tags($form['attributes']['fields']['wrapper_class'], $opt); acfe_apply_tags($form['attributes']['fields']['class'], $opt); acfe_apply_tags($form['attributes']['submit']['value'], $opt); acfe_apply_tags($form['attributes']['submit']['button'], $opt); acfe_apply_tags($form['attributes']['submit']['spinner'], $opt); acfe_apply_tags($form['validation']['errors_class'], $opt); // deprecated if(isset($form['return'])){ acfe_apply_tags($form['return'], $opt); } // load form per action foreach($form['actions'] as $action){ // tags context acfe_add_context('action', $action); // load action $form = apply_filters("acfe/form/load_{$action['action']}", $form, $action); $form = apply_filters("acfe/form/load_{$action['action']}/form={$form['name']}", $form, $action); $form = apply_filters("acfe/form/load_{$action['action']}/action={$action['name']}", $form, $action); // tags context acfe_delete_context('action'); } // update context acfe_add_context('form', $form); return $form; } /** * render_form * * @param $form */ function render_form($form){ // get form $form = $this->get_form($form); // tags context acfe_add_context('form', $form); acfe_add_context('method', 'load'); // load form $form = apply_filters('acfe/form/load_form', $form); // validate if(!$form || empty($form['active'])){ return; } // update context // used in prepare_field_attributes() & prepare_field_values() acfe_add_context('form', $form); // enqueue acf acf_enqueue_scripts(); $data = array(); $data = apply_filters("acfe/form/set_form_data", $data, $form); $data = apply_filters("acfe/form/set_form_data/form={$form['name']}", $data, $form); if($data){ acfe_set_form_data($form, $data); } // override acf.data.post_id add_action('wp_print_footer_scripts', array($this, 'override_acf_post_id'), 9); // render success only once // this allows to render the same form within the success message with [acfe_form] // do not execute in ajax so form displayed in success message using ajax submission doesn't display success twice if(acfe_is_form_success($form) && !acf_did('acfe/form/success') && !acf_is_ajax()){ // render success $this->render_success($form); // add success class $form['attributes']['form']['class'] .= !empty($form['attributes']['form']['class']) ? ' ' : ''; $form['attributes']['form']['class'] .= '-success'; // hide form if($form['success']['hide_form']){ return; } } // prepare form $form = apply_filters("acfe/form/prepare_form", $form); // validate if(!$form){ return; } // hooks do_action("acfe/form/render_before_form", $form); do_action("acfe/form/render_before_fields", $form); do_action("acfe/form/render_fields", $form); do_action("acfe/form/render_after_fields", $form); if($form['attributes']['submit']){ do_action("acfe/form/render_submit", $form); } do_action("acfe/form/render_after_form", $form); } /** * render_success * * @param $form * * @return void */ function render_success($form){ $setup_meta = !acfe_is_local_meta() && !empty($_POST['acf']); if($setup_meta){ acfe_setup_meta(wp_unslash($_POST['acf']), 'acfe/form/success', true); } // apply tags // wysiwyg is formatted later with acf_the_content filter in render_success() acfe_apply_tags($form['success']['wrapper'], array('context' => 'display')); acfe_apply_tags($form['success']['message'], array('context' => 'display', 'unformat' => 'wysiwyg')); // hook do_action('acfe/form/render_success', $form); if($setup_meta){ acfe_reset_meta(); } } /** * set_form_data * * @param $data * @param $form * * @return mixed */ function set_form_data($data, $form){ $data['cid'] = $form['cid']; $data['name'] = $form['name']; $data['id'] = $form['ID']; $data['field_class'] = $form['attributes']['fields']['class']; $data['hide_error'] = $form['validation']['hide_error']; $data['hide_unload'] = $form['validation']['hide_unload']; $data['hide_revalidation'] = $form['validation']['hide_revalidation']; $data['error_position'] = $form['validation']['errors_position']; $data['error_class'] = $form['validation']['errors_class']; $data['messages'] = $form['validation']['messages']; $data['scroll'] = $form['success']['scroll']; $data['hide_form'] = $form['success']['hide_form']; $data['success'] = false; return $data; } /** * get_form_validation * * @return array|false */ function get_form_validation(){ $valid_screen = acfe_is_front() && acf_maybe_get_POST('_acf_screen') === 'acfe_form'; $form = acfe_get_form_sent(); if($valid_screen && $form){ return $form; } return false; } /** * get_form_submission * * @return array|false */ function get_form_submission(){ $valid_screen = acf_verify_nonce('acfe_form'); $form = acfe_get_form_sent(); if($valid_screen && $form){ return $form; } return false; } /** * set_data * * @param $form * @param $path * @param $value * * @return void */ function set_data($form, $path = null, $value = null){ if($value === null){ $value = $path; $path = null; } // append data for acf.data if($form['cid']){ // determine path $data_path = $path ? "forms.{$form['cid']}.{$path}" : "forms.{$form['cid']}"; // localize acfe_set_localize_data($data_path, $value); } } /** * override_acf_post_id * * wp_print_footer_scripts * * Override acf.data.post_id to use page id and not form post_id * Multiple acfe_form() in a WP_Query loop will assign acf.data.post_id to the last post * * @return void */ function override_acf_post_id(){ // only once if(!acf_did('acfe/form/override_acf_post_id')){ acf_set_form_data('post_id', acfe_get_post_id()); } } /** * prevent_refresh * * wp_print_footer_scripts * * Avoid multiple submissions on page refresh * * @return void */ function prevent_refresh(){ ?> <script> if(window.history.replaceState){ window.history.replaceState(null, null, window.location.href); } </script> <?php } /** * render_form_ajax * * @return void */ function render_form_ajax(){ // validate ajax if(!acf_verify_ajax()){ die; } // parse options $options = wp_parse_args($_POST, array( 'form' => false, )); // render form if(!empty($options['form'])){ acfe_form($options['form']); } die; } /** * get_form_data * * @return array|false */ function get_form_data(){ return acfe_get_form_sent(); } } acf_new_instance('acfe_module_form_front'); endif; /** * acfe_form * * @param $form */ function acfe_form($form = array()){ acf_get_instance('acfe_module_form_front')->render_form($form); } /** * acfe_get_form * * @param array $form * * @return mixed */ function acfe_get_form(array $form = array()){ return acf_get_instance('acfe_module_form_front')->get_form($form); } /** * acfe_set_form_data * * @param $form * @param $value * * @return void */ function acfe_set_form_data($form, $path = null, $value = null){ acf_get_instance('acfe_module_form_front')->set_data($form, $path, $value); }