documents->get($step_id); $form = null; if ($document) { $form = Utils::find_element_recursive($document->get_elements_data(), $post_data['form_id']); } if (empty($form)) { $results = array( 'message' => 'invalid_form', 'success' => false ); echo json_encode($results); die(); } $widget = $elementor->elements_manager->create_element_instance($form); $form['settings'] = $widget->get_settings_for_display(); unset($post_data['post_id']); unset($post_data['form_id']); $record = new Optin_Record($post_data, $form); $fields = $record->get_fields(); $name = ''; if ($fields) { foreach ($fields as $key => $value) { if ('email' === $key) { $name = strstr($value, '@', true);; } elseif ('last_name' === $key) { $name = $value; } elseif ('first_name' === $key) { $name = $value; } } } $response = array( 'success' => true, 'post_action' => 'notification', 'notification_text' => '', 'redirect_url' => '#' ); $post_action = $form['settings']['post_action']; $response['post_action'] = $post_action; $action_type = ''; $response['notification_text'] = isset($form['settings']['notification_text']) && $form['settings']['notification_text'] ? $form['settings']['notification_text'] : ''; $next_step = []; switch ($post_action) { case 'notification': $response['redirect'] = false; break; case 'redirect_to': $action_type = 'redirect_to_url'; $response['redirect'] = true; if (!empty($form['settings']['redirect_url'])) { $response['redirect_url'] = add_query_arg( $this->prepare_query_param($name,$query), $form['settings']['redirect_url']['url']); } else { $response['redirect_url'] = '#'; } break; default: $action_type = 'next_step'; $next_step = Wpfnl_functions::get_next_step($funnel_id, $step_id); $response['redirect_url'] = add_query_arg( $this->prepare_query_param($name,$query), get_the_permalink($next_step['step_id'])); $response['redirect'] = true; } $admin_email = isset($form['settings']['admin_email']) ? $form['settings']['admin_email'] : false; $admin_email_subject = isset($form['settings']['admin_email_subject']) ? $form['settings']['admin_email_subject'] : 'Opt-in form Submission'; $user_info = $record->form_data; /** * User registration */ if (!empty($user_info['optin_allow_registration']) && $user_info['optin_allow_registration'] == 'yes') { $this->create_user_optin_allow_registration($name, $user_info); } /** * Recaptcha Check */ $is_recaptcha = isset($post_data['wpf-is-recapcha']) ? $post_data['wpf-is-recapcha'] : 'no'; $recaptcha_site_key = isset($post_data['wpf-optin-g-token']) ? $post_data['wpf-optin-g-token'] : ''; $recaptcha_site_secrect = isset($post_data['wpf-optin-g-secret-key']) ? $post_data['wpf-optin-g-secret-key'] : ''; $response = $this->send_mail_after_checking_google_recaptcha_response($is_recaptcha, $recaptcha_site_key, $recaptcha_site_secrect, $admin_email, $admin_email_subject, $user_info, $response); /** * Submit & process form data */ ob_start(); do_action('wpfunnels/after_optin_submit', $step_id, $post_action, $action_type, $record, $post_data); ob_get_clean(); if (!empty($next_step['step_type']) && 'conditional' == $next_step['step_type']) { $next_step = $this->match_conditional_step($next_step, $funnel_id, $step_id ); $response['redirect_url'] = add_query_arg( $this->prepare_query_param($name,$query), get_the_permalink($next_step['step_id'])); } if( isset($next_step['step_type']) && 'thankyou' === $next_step['step_type'] ){ $custom_url = Wpfnl_functions::custom_url_for_thankyou_page( $next_step['step_id'] ); if( $custom_url ){ $response['redirect_url'] = $custom_url; } } echo json_encode($response, true); die(); } /** * Prepare query param for redirect url * * @param String $name * @param Array $query * * @return Array * @since 2.5.9 */ private function prepare_query_param( $name, $query ){ $query_param['optin'] = true; $query_param['uname'] = $name; if( isset($query['wpfnl-order'], $query['wpfnl-key']) ){ $query_param['wpfnl-order'] = $query['wpfnl-order']; $query_param['wpfnl-key'] = $query['wpfnl-key']; } return $query_param; } /** * Optin submission handling for shortcode * * @since @since 2.5.7 * @return void */ public function wpfnl_shortcode_optin_submission() { check_ajax_referer( 'optin_form_nonce', 'security' ); $response = [ 'success' => true, 'post_action' => 'notification', 'notification_text' => '', 'redirect_url' => '#' ]; $postData = filter_input( INPUT_POST, 'postData' ); wp_parse_str( $postData, $post_data ); if( !empty( $post_data ) ) { $post_data[ 'email' ] = !empty( $post_data[ 'email' ] ) && is_email( $post_data[ 'email' ] ) ? strtolower( sanitize_email( $post_data[ 'email' ] ) ) : ''; $parts = wp_parse_url( filter_input( INPUT_POST, 'url', FILTER_VALIDATE_URL ) ); $parts_query = $parts[ 'query' ] ?? ''; wp_parse_str( $parts_query, $query ); $funnel_id = filter_input( INPUT_POST, 'funnel_id', FILTER_VALIDATE_INT ); $step_id = filter_input( INPUT_POST, 'step_id', FILTER_VALIDATE_INT ); $post_action = $post_data[ 'post_action' ] ?? 'notification'; $response[ 'post_action' ] = $post_action; $response[ 'notification_text' ] = $post_data[ 'notification_text' ] ?? ''; $user_info = $this->extract_user_info( $post_data ); $name = $user_info[ 'email' ] ? strstr( $user_info[ 'email' ], '@', true ) : ''; $query_params = $this->prepare_query_param( $name, $query ); $actions = $this->process_post_action( $post_action, $post_data, $response, $query_params, $step_id, $funnel_id ); $response = $actions[ 'response' ] ?? $response; $next_step = $actions[ 'next_step' ] ?? []; $action_type = $actions[ 'action_type' ] ?? ''; /** * Filters the response after opt-in for submission. * * This filter hook allows developers to modify or override the response generated * for an opt-in form submission. * * @param array $response The response generated after opt-in for submission. * @param array $post_data The post data received from the opt-in form submission. * @param array $user_info The user information extracted from the form submission. * @return array Modified response array. * * @since 2.8.2 */ $response = apply_filters( 'wpfunnels/optin_submission_response', $this->process_recaptcha( $post_data, $response, $user_info ), $funnel_id, $step_id, $next_step, $query_params ); $record = new \stdClass(); $record->form_data = $user_info; if( isset($next_step['step_type']) && 'thankyou' === $next_step['step_type'] ){ $custom_url = Wpfnl_functions::custom_url_for_thankyou_page( $next_step['step_id'] ); if( $custom_url ){ $response['redirect_url'] = $custom_url; } } /** * Fires after an opt-in form submission in a funnel step. * * This action hook is triggered after the submission of an opt-in form in a funnel step. * It provides the opportunity to perform additional actions or processes after the opt-in form is submitted. * * @param int $step_id The ID of the funnel step where the opt-in form was submitted. * @param string $post_action The type of action taken after form submission (e.g., 'notification', 'redirect_to', 'next_step'). * @param string $action_type The type of action that determined the redirection or next step behavior. * @param object $record An object containing data related to the form submission. * @param array $post_data The post data received from the form submission. * * @since @since 2.5.7 */ ob_start(); do_action('wpfunnels/after_optin_submit', $step_id, $post_action, $action_type, $record, $post_data); ob_get_clean(); echo json_encode( $response, true ); } die(); } /** * Extracts user information from the provided post data. * * This function extracts specific user information fields from the given post data. * The function iterates through a predefined list of user fields and extracts * their values from the post data. * * @param array $post_data The post data containing user information. * * @return array The extracted user information as an associative array. * @since 2.8.2 */ private function extract_user_info( $post_data ) { $user_info = []; $user_fields = [ 'email', 'last_name', 'first_name', 'phone', 'web-url', 'message', 'data_to_checkout' ]; // Iterate through user fields and extract their values from post data foreach( $user_fields as $key ) { if( !empty( $post_data[ $key ] ) ) { $user_info[ $key ] = $post_data[ $key ]; } } return $user_info; } /** * Processes the post action based on the provided data and returns relevant response information. * * This function takes the post action, post data, response, query parameters, step ID, and funnel ID * to determine the appropriate action and response details. It handles different post action cases, * such as 'notification', 'redirect_to', and the default case. It prepares the necessary response data * including whether a redirect is required, the action type, and the next step information. * * @param string $post_action The post action type. * @param array $post_data The post data containing user inputs. * @param array $response The current response data. * @param array $query_params The query parameters to add to the URL. * @param int $step_id The ID of the current step. * @param int $funnel_id The ID of the current funnel. * * @return array An associative array containing the updated response, next step information, and action type. * @since 2.8.2 */ private function process_post_action( $post_action, $post_data, $response, $query_params, $step_id, $funnel_id ) { switch( $post_action ) { case 'notification': $response[ 'redirect' ] = false; break; case 'redirect_to': $response[ 'redirect' ] = true; $action_type = 'redirect_to_url'; if( !empty( $post_data[ 'redirect_url' ] ) ) { if( 'next_step' !== $post_data[ 'redirect_url' ] ) { $response[ 'redirect_url' ] = add_query_arg( $query_params, $post_data[ 'redirect_url' ] ); break; } $action_type = 'next_step'; $next_step = $funnel_id ? Wpfnl_functions::get_next_step( $funnel_id, $step_id ) : ''; if( $next_step ) { $response[ 'redirect_url' ] = add_query_arg( $query_params, get_the_permalink( $next_step[ 'step_id' ] ) ); break; } $response[ 'redirect_url' ] = '#'; break; } $response[ 'redirect_url' ] = '#'; break; default: $action_type = 'next_step'; $next_step = $funnel_id ? Wpfnl_functions::get_next_step( $funnel_id, $step_id ) : ''; if( $next_step ) { $response[ 'redirect_url' ] = add_query_arg( $query_params, get_the_permalink( $next_step[ 'step_id' ] ) ); } else { $response[ 'redirect_url' ] = '#'; } $response[ 'redirect' ] = true; } return [ 'response' => $response, 'next_step' => $next_step ?? [], 'action_type' => $action_type ?? '' ]; } /** * Processes reCAPTCHA and sends an email after checking Google reCAPTCHA response. * * This function takes the post data, response, and user information, and processes reCAPTCHA * by checking the Google reCAPTCHA response. It then sends an email with the provided user information. * * @param array $post_data The post data containing user inputs and reCAPTCHA details. * @param array $response The current response data. * @param array $user_info The user information to include in the email. * * @return array The updated response after processing reCAPTCHA and sending the email. * @since 2.8.2 */ private function process_recaptcha( $post_data, $response, $user_info ) { $admin_email = $post_data[ 'admin_email' ] ?? false; $admin_email_subject = $post_data[ 'admin_email_subject' ] ?? 'Opt-in form Submission'; $is_recaptcha = $post_data[ 'wpf-is-recapcha' ] ?? 'false'; $recaptcha_site_key = $post_data[ 'wpf-optin-g-token' ] ?? ''; $recaptcha_site_secrect = $post_data[ 'wpf-optin-g-secret-key' ] ?? ''; return $this->send_mail_after_checking_google_recaptcha_response( $is_recaptcha, $recaptcha_site_key, $recaptcha_site_secrect, $admin_email, $admin_email_subject, $user_info, $response ); } /** * Gutenberg opt-in form handling * * @return void * @since 2.5.9 */ public function gutenberg_optin_form_submission() { check_ajax_referer('optin_form_nonce', 'security'); $step_id = isset($_POST['step_id']) ? $_POST['step_id'] : ''; $postData = isset($_POST['postData']) ? $_POST['postData'] : ''; $funnel_id = Wpfnl_functions::get_funnel_id_from_step($step_id); $post_data = array(); parse_str($postData, $post_data); if (isset($post_data['email'])){ $post_data['email'] = strtolower($post_data['email']); } $post_id = $step_id; $post = get_post($post_id); $all_blocks = parse_blocks($post->post_content); $url = isset($_POST['url']) ? $_POST['url'] : ''; $parts = parse_url($url); $query = []; if( isset($parts['query']) ){ parse_str($parts['query'], $query); } $admin_email = ''; $admin_email_subject = ''; $post_action = ''; $block_attr = array(); $record = new Optin_Record($post_data); $fields = $record->get_fields(); $name = ''; if ($fields) { foreach ($fields as $key => $value) { if ('email' === $key) { $name = strstr($value,'@',true); } elseif( 'last_name' === $key ) { $name = $value; } elseif ('first_name' === $key) { $name = $value; } } } $response = array( 'success' => true, 'post_action' => 'notification', 'notification_text' => '', 'redirect_url' => '#' ); $custom_url = ''; $blocks = $this->search_items_by_key($all_blocks, 'blockName'); foreach ($blocks as $block) { if ($block['blockName'] == 'wpfunnels/optin-form') { $block_attr = $block['attrs']; $admin_email = isset($block_attr['adminEmail']) ? $block_attr['adminEmail'] : ''; $admin_email_subject = isset($block_attr['emailSubject']) ? $block_attr['emailSubject'] : 'Opt-in form Submission'; $post_action = isset($block_attr['postAction']) ? $block_attr['postAction'] : 'notification'; $custom_url = isset($block_attr['redirect_url']) ? $block_attr['redirect_url'] : '#'; } } $response['notification_text'] = isset($block_attr['notification']) ? $block_attr['notification'] : ''; $next_step = []; switch ($post_action) { case 'notification': $action_type = 'notification'; $response['redirect'] = false; break; case 'redirect_to': $action_type = 'redirect_to_url'; $response['redirect'] = true; $response['post_action'] = $post_action; if ($custom_url) { $response['redirect_url'] = add_query_arg($this->prepare_query_param($name,$query), $custom_url); } else { $response['redirect_url'] = '#'; } break; case 'next_step': $response['post_action'] = $post_action; $action_type = 'next_step'; $next_step = Wpfnl_functions::get_next_step($funnel_id, $step_id); $response['redirect_url'] = add_query_arg($this->prepare_query_param($name,$query), get_the_permalink($next_step['step_id'])); $response['redirect'] = true; break; default: $action_type = 'next_step'; $next_step = Wpfnl_functions::get_next_step($funnel_id, $step_id); $response['redirect_url'] = add_query_arg($this->prepare_query_param($name,$query), get_the_permalink($next_step['step_id'])); $response['redirect'] = true; } /** * User registration */ if (!empty($post_data['optin_allow_registration']) && $post_data['optin_allow_registration'] == 'yes') { $this->create_user_optin_allow_registration($name, $post_data); } /** * Check google Recaptcha V3 */ $is_recaptcha = isset($post_data['wpf-is-recapcha']) ? $post_data['wpf-is-recapcha'] : 'false'; $recaptcha_site_key = isset($post_data['wpf-optin-g-token']) ? $post_data['wpf-optin-g-token'] : ''; $recaptcha_site_secrect = isset($post_data['wpf-optin-g-secret-key']) ? $post_data['wpf-optin-g-secret-key'] : ''; $response = $this->send_mail_after_checking_google_recaptcha_response($is_recaptcha, $recaptcha_site_key, $recaptcha_site_secrect, $admin_email, $admin_email_subject, $post_data, $response); ob_start(); do_action('wpfunnels/after_optin_submit', $step_id, $post_action, $action_type, $record, $post_data); ob_get_clean(); if (!empty($next_step['step_type']) && 'conditional' == $next_step['step_type']) { $next_step = $this->match_conditional_step($next_step, $funnel_id, $step_id ); $response['redirect_url'] = add_query_arg($this->prepare_query_param($name,$query), get_the_permalink($next_step['step_id'])); } if( isset($next_step['step_type']) && 'thankyou' === $next_step['step_type'] ){ $custom_url = Wpfnl_functions::custom_url_for_thankyou_page( $next_step['step_id'] ); if( $custom_url ){ $response['redirect_url'] = $custom_url; } } echo json_encode($response, true); die(); } /** * Search array item by key * * @param Array $array * @param String $key * * @return Array * @since 2.5.9 */ private function search_items_by_key($array, $key) { $results = array(); if (is_array($array)) { if (isset($array[$key]) && key($array) == $key) if ($array[$key] == 'wpfunnels/optin-form') { $results[] = $array; } foreach ($array as $sub_array) $results = array_merge($results, $this->search_items_by_key($sub_array, $key)); } return $results; } /** * Send email to admin * * @param String $email * @param String $subject * @param Array $user_info * * @return void * @since 2.5.9 */ private function send_email_to_admin($emails = '', $subject = '', $user_info = []) { $email_array = explode(",", $emails); if (is_array($email_array)) { foreach ($email_array as $email) { if ($email) { $email = trim($email); $current_date = date("d M Y"); $time = new \DateTimeImmutable('now', wp_timezone()); $current_time = $time->format("h:i A"); $poweredBy = __('WPFunnels', 'wpfnl'); $info = ''; if (isset($user_info['first_name']) && $user_info['first_name']) { $info .= "First Name : {$user_info['first_name']}
"; } if (isset($user_info['last_name']) && $user_info['last_name']) { $info .= "Last Name : {$user_info['last_name']}
"; } if (isset($user_info['email']) && $user_info['email']) { $info .= "Email : {$user_info['email']}

"; } if (isset($user_info['phone']) && $user_info['phone']) { $info .= "Phone : {$user_info['phone']}

"; } if (isset($user_info['web-url']) && $user_info['web-url']) { $esc_url = esc_url($user_info['web-url']); $info .= "Website URL : {$esc_url}

"; } if (isset($user_info['message']) && $user_info['message']) { $esc_html = esc_html($user_info['message']); $info .= "Message : {$esc_html}

"; } $info .= "----

Date : {$current_date}
Time : {$current_time}
Powered by : {$poweredBy}
"; $email_body = $info; if (!$subject) { $subject = 'New Submission'; } $headers = ['Content-Type: text/html; charset=UTF-8']; wp_mail($email, $subject, $email_body, $headers); } } } } /** * Create User as a subscriber * When allow the subscriber option for registration from builder * * @param $name * @param $post_data * * @since 2.5.9 */ public static function create_user_optin_allow_registration( $name, $post_data ) { $exist_user_by_username = get_user_by('login', $name); $exist_user_by_email = get_user_by('email', $post_data['email']); if (empty($exist_user_by_email) || empty($exist_user_by_username)) { $data = array( 'user_login' => $name, 'user_email' => isset($post_data['email']) ? $post_data['email'] : '', 'first_name' => isset($post_data['first_name']) ? $post_data['first_name'] : '', 'last_name' => isset($post_data['last_name']) ? $post_data['last_name'] : '', 'user_pass' => wp_generate_password(6, false), 'role' => 'subscriber', ); if (isset($post_data['web-url'])) { $data['user_url'] = $post_data['web-url']; } $user_id = wp_insert_user($data); if (isset($post_data['phone'])) { update_user_meta($user_id, 'phone', $post_data['phone']); } if (!is_wp_error($user_id)) { wp_send_new_user_notifications($user_id, $notify = 'both'); } } } /** * Check Google recaptcha Response and Send mail * * @param $is_recaptcha * @param $recaptcha_site_key * @param $recaptcha_site_secrect * * @since 2.5.9 */ private function send_mail_after_checking_google_recaptcha_response($is_recaptcha, $recaptcha_site_key, $recaptcha_site_secrect, $admin_email, $admin_email_subject, $post_data, $response) { $recaptcha_response = []; if ($recaptcha_site_key && $recaptcha_site_secrect && 'on' === $is_recaptcha) { $recaptcha_response = Google_Recaptcha_Handler::get_response_recaptcha($recaptcha_site_secrect, $recaptcha_site_key); } if ('on' === $is_recaptcha) { if ($admin_email && $admin_email_subject && isset($post_data['email']) && $post_data['email'] && isset($recaptcha_response->success) && $recaptcha_response->success) { $this->send_email_to_admin($admin_email, $admin_email_subject, $post_data); } else { $response['notification_text'] = __("reCAPTCHA is not Correct", 'wpfnl'); $response['success'] = false; return $response; } } else { if ($admin_email && $admin_email_subject && isset($post_data['email']) && $post_data['email']) { $this->send_email_to_admin($admin_email, $admin_email_subject, $post_data); } } return $response; } /** * Match ption submit condition * * @param Array $next_step * @param Number $funnel_id * * @return Array $next_step * @since 2.5.7 */ public static function match_conditional_step($next_step, $funnel_id, $step_id ) { $condition = Wpfnl_Condition_Checker::getInstance(); $condition_identifier = strval($next_step['step_id']); $data['step_id'] = $step_id; $condition_matched = $condition->check_condition($funnel_id, $data, $condition_identifier); $next_node = Wpfnl_functions::get_next_step($funnel_id, $condition_identifier, $condition_matched); $next_node = apply_filters('wpfunnels/next_step_data', $next_node); return $next_node; } }