[ $slug ], FLUENTFORM_FRAMEWORK_UPGRADE, 'fluentform/conversational_url_slug', 'Use fluentform/conversational_url_slug instead of fluentform_conversational_url_slug.' ); $paramKey = apply_filters('fluentform/conversational_url_slug', $paramKey); if ('form' == $paramKey) { $paramKey = $slug; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public form display, no nonce needed if(!isset($_REQUEST[$paramKey])) { return; } $request = wpFluentForm('request')->get(); if ((isset($request[$paramKey])) && !wp_doing_ajax()) { $formId = (int) ArrayHelper::get($request, $paramKey); if (!Helper::isConversionForm($formId)) { return; } $shareKey = ArrayHelper::get($request, 'form'); $this->renderFormHtml($formId, $shareKey); } } public function isEnabled() { $globalModules = get_option('fluentform_global_modules_status'); $addOn = ArrayHelper::get($globalModules, $this->addOnKey); if (!$addOn || 'yes' == $addOn) { return true; } return false; } private function getSubmitBttnStyle($form) { $data = $form->submit_button; $styles = ''; if ('' == ArrayHelper::get($data, 'settings.button_style')) { // it's a custom button $buttonActiveStyles = ArrayHelper::get($data, 'settings.normal_styles', []); $buttonHoverStyles = ArrayHelper::get($data, 'settings.hover_styles', []); $activeStates = ''; foreach ($buttonActiveStyles as $styleAtr => $styleValue) { if ('0' != $styleValue && !$styleValue) { continue; } if ('borderRadius' == $styleAtr) { $styleValue .= 'px'; } $activeStates .= ltrim(strtolower(preg_replace('/[A-Z]([A-Z](?![a-z]))*/', '-$0', $styleAtr)), '_') . ':' . $styleValue . ';'; } if ($activeStates) { $styles .= ' .ff-btn-submit { ' . $activeStates . ' }'; } $hoverStates = ''; foreach ($buttonHoverStyles as $styleAtr => $styleValue) { if ('0' != $styleValue && !$styleValue) { continue; } if ('borderRadius' == $styleAtr) { $styleValue .= 'px'; } $hoverStates .= ltrim(strtolower(preg_replace('/[A-Z]([A-Z](?![a-z]))*/', '-$0', $styleAtr)), '-') . ':' . $styleValue . ';'; } if ($hoverStates) { $styles .= ' .wpf_has_custom_css.ff-btn-submit:hover { ' . $hoverStates . ' } '; } } else { $styles .= ' .ff-btn-submit { background-color: ' . ArrayHelper::get($data, 'settings.background_color') . '; color: ' . ArrayHelper::get($data, 'settings.color') . '; }'; } if (defined('FLUENTFORMPRO')) { $customCssJsClass = new FormCssJs(); $customCss = $customCssJsClass->getCss($form->id); $styles .= $customCss; } return $styles; } public function filterAcceptedFields($components, $formId) { if (!Helper::isConversionForm($formId)) { return $components; } $generalFields = ArrayHelper::get($components, 'general', []); $advancedFields = ArrayHelper::get($components, 'advanced', []); $paymentFields = ArrayHelper::get($components, 'payments', []); $acceptedFieldElements = [ 'phone', 'select', 'select', 'ratings', 'textarea', 'address', 'input_name', 'input_url', 'input_text', 'input_date', 'input_file', 'input_email', 'input_radio', 'custom_html', 'input_image', 'input_hidden', 'input_number', 'tabular_grid', 'section_break', 'select_country', 'input_checkbox', 'input_password', 'terms_and_condition', 'gdpr_agreement', 'multi_payment_component', 'subscription_payment_component', 'custom_payment_component', 'item_quantity_component', 'payment_method', 'payment_summary_component', 'payment_coupon', 'recaptcha', 'hcaptcha', 'turnstile', 'quiz_score', 'save_progress_button', 'dynamic_field', 'rangeslider', 'net_promoter_score' ]; if (defined('FLUENTFORM_SIGNATURE')) { $acceptedFieldElements[] = 'signature'; } $acceptedFieldElements = apply_filters( 'fluentform/conversational_accepted_field_elements', $acceptedFieldElements, $formId ); $elements = []; $allFields = [ 'general' => $generalFields, 'advanced' => $advancedFields, 'payments' => $paymentFields, ]; foreach ($allFields as $groupType => $group) { foreach ($group as $field) { $element = $field['element']; if (in_array($element, $acceptedFieldElements)) { $field['style_pref'] = [ 'layout' => 'default', 'media' => fluentFormGetRandomPhoto(), 'brightness' => 0, 'alt_text' => '', 'media_x_position' => 50, 'media_y_position' => 50, ]; if ('terms_and_condition' == $element || 'gdpr_agreement' == $element) { $existingSettings = $field['settings']; $existingSettings['tc_agree_text'] = __('I accept', 'fluentform'); if ('terms_and_condition' == $element) { $existingSettings['tc_dis_agree_text'] = __('I don\'t accept', 'fluentform'); $existingSettings['hide_disagree'] = false; } $field['settings'] = $existingSettings; } //adding required settings for captcha in conversational form if ('hcaptcha' == $element || 'recaptcha' == $element || 'turnstile' == $element) { $existingSettings = $field['settings']; if (empty($existingSettings['validation_rules'])) { $existingSettings['validation_rules'] = [ 'required' => [ 'value' => true, 'message' => __('This field is required', 'fluentform'), ], ]; } $field['settings'] = $existingSettings; } $elements[$groupType][] = $field; } } } $elements = apply_filters_deprecated( 'fluent_conversational_editor_elements', [ $elements ], FLUENTFORM_FRAMEWORK_UPGRADE, 'fluentform/conversational_editor_elements', 'Use fluentform/conversational_editor_elements instead of fluent_conversational_editor_elements.' ); $elements = apply_filters('fluentform/conversational_editor_elements', $elements, $formId); return $elements; } public function printLoadedScripts() { $jsScripts = $this->getRegisteredScripts(); if ($jsScripts) { add_action('fluentform/conversational_frame_footer', function () use ($jsScripts) { foreach ($jsScripts as $handle => $jsScript) { if (empty($jsScript->src)) { continue; } if ($data = ArrayHelper::get($jsScript->extra, 'data')) { printf("\n"; } $src = $jsScript->src; $src = add_query_arg('ver', $jsScript->ver, $src); echo "\n"; } }, 1); } $cssStyles = $this->getRegisteredStyles(); if ($cssStyles) { add_action('fluentform/conversational_frame_head', function () use ($cssStyles) { foreach ($cssStyles as $styleName => $cssStyle) { if (empty($cssStyle->src)) { continue; } $src = add_query_arg('ver', $cssStyle->ver, $cssStyle->src); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet -- Completely a custom rendering page. echo "\n"; } }); } } private function getRegisteredScripts() { global $wp_scripts; if (!$wp_scripts) { return []; } $jsScripts = []; $pluginUrl = plugins_url() . '/fluentform'; foreach ($wp_scripts->queue as $script) { if (!isset($wp_scripts->registered[$script])) { continue; } $item = $wp_scripts->registered[$script]; $src = $wp_scripts->registered[$script]->src; if (false === !strpos($src, $pluginUrl)) { continue; } foreach ($item->deps as $dep) { if (isset($wp_scripts->registered[$dep])) { $child = $wp_scripts->registered[$dep]; if ($child->src) { $jsScripts[$dep] = $child; } else { // this core file maybe $childDependencies = $child->deps; foreach ($childDependencies as $childDependency) { $childX = $wp_scripts->registered[$childDependency]; if ($childX->src) { $jsScripts[$childDependency] = $childX; } } } } } $jsScripts[$script] = $item; } return $jsScripts; } private function getRegisteredStyles() { $wp_styles = wp_styles(); if (!$wp_styles) { return []; } $cssStyles = []; $pluginUrl = plugins_url() . '/fluentform'; foreach ($wp_styles->queue as $style) { if (!isset($wp_styles->registered[$style])) { continue; } $item = $wp_styles->registered[$style]; $src = $wp_styles->registered[$style]->src; if (false === !strpos($src, $pluginUrl)) { continue; } if ($item->deps) { foreach ($item->deps as $dep) { if (isset($wp_styles->registered[$dep])) { $child = $wp_styles->registered[$dep]; if ($child->src) { $cssStyles[$dep] = $child; } else { // this core file maybe $childDependencies = $child->deps; if ($childDependencies && is_array($childDependencies)) { foreach ($childDependencies as $childDependency) { $childX = $wp_styles->registered[$childDependency]; if ($childX->src) { $cssStyles[$childDependency] = $childX; } } } } } } } $cssStyles[$style] = $item; } return $cssStyles; } public function renderShortcode($form) { $formId = $form->id; $form = Converter::convert($form); $this->enqueueScripts(); $submitCss = $this->getSubmitBttnStyle($form); $metaSettings = $this->getMetaSettings($formId); $designSettings = $this->getDesignSettings($formId); $instanceId = $form->instance_index; $varName = 'fluent_forms_global_var_' . $instanceId; wp_localize_script('fluent_forms_conversational_form', $varName, [ 'fluent_forms_admin_nonce' => wp_create_nonce('fluent_forms_admin_nonce'), 'ajaxurl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce(), 'form' => $this->getLocalizedForm($form), 'assetBaseUrl' => FLUENT_CONVERSATIONAL_FORM_DIR_URL . 'public', 'i18n' => $metaSettings['i18n'], 'form_id' => $form->id, 'hasPro' => defined('FLUENTFORMPRO'), 'is_inline_form' => true, 'design' => $designSettings, 'extra_inputs' => $this->getExtraHiddenInputs($formId), 'uploading_txt' => __('Uploading', 'fluentform'), 'upload_completed_txt' => __('100% Completed', 'fluentform'), 'paymentConfig' => $this->getPaymentConfig($form), 'date_i18n' => \FluentForm\App\Modules\Component\Component::getDatei18n(), 'file_delete_nonce' => wp_create_nonce('fluentform_file_delete') ]); $hasSaveProgressButton = false; $saveProgressButton = []; foreach ($form->fields['fields'] as $item) { if (isset($item['element']) && $item['element'] === 'save_progress_button') { $hasSaveProgressButton = true; $saveProgressButton = $item; } } if ($hasSaveProgressButton && $saveProgressButton) { $this->localizeSaveProgressButton($saveProgressButton, $formId); } /* This filter is deprecated and will be removed soon */ $disableAnalytics = apply_filters('fluentform-disabled_analytics', true); if (!apply_filters('fluentform/disabled_analytics', $disableAnalytics)) { if (!Acl::hasAnyFormPermission($form->id)) { (new \FluentForm\App\Services\Analytics\AnalyticsService())->store($formId); } } return wpFluentForm('view')->make('public.conversational-form-inline', [ 'generated_css' => $this->getGeneratedCss($formId), 'design' => $designSettings, 'submit_css' => $submitCss, 'form_id' => $formId, 'meta' => $metaSettings, 'global_var_name' => $varName, 'instance_id' => $instanceId, 'is_inline' => 'yes', ]); } public function maybeAlterPlacement($placements, $form) { if (!Helper::isConversionForm($form->id) || empty($placements['terms_and_condition']) || empty($placements['gdpr_agreement'])) { return $placements; } $placements['terms_and_condition']['general'] = [ 'admin_field_label', 'validation_rules', 'tnc_html', 'tc_agree_text', 'tc_dis_agree_text', ]; $placements['terms_and_condition']['generalExtras'] = [ 'tc_agree_text' => [ 'template' => 'inputText', 'label' => 'Agree Button Text', ], 'tc_dis_agree_text' => [ 'template' => 'inputText', 'label' => 'Disagree Button Text', ], 'hide_disagree' => [ 'template' => 'inputCheckbox', 'options' => [ [ 'value' => false, 'label' => __('Hide Disagree Button', 'fluentform'), ], ], ], ]; $placements['gdpr_agreement']['generalExtras'] = [ 'tc_agree_text' => [ 'template' => 'inputText', 'label' => 'Agree Option Text', ], ]; return $placements; } private function getExtraHiddenInputs($formId) { return [ '__fluent_form_embded_post_id' => get_the_ID(), '_fluentform_' . $formId . '_fluentformnonce' => wp_create_nonce('fluentform-submit-form'), '_wp_http_referer' => esc_attr(wp_unslash(wpFluentForm('request')->server('REQUEST_URI'))), ]; } public function getRandomPhoto() { return fluentFormGetRandomPhoto(); } private function renderFormHtml($formId, $providedKey = '') { $form = wpFluent()->table('fluentform_forms')->find($formId); if (!$form) { return ''; } $formSettings = wpFluent() ->table('fluentform_form_meta') ->where('form_id', $formId) ->where('meta_key', 'formSettings') ->first(); if (!$formSettings) { return ''; } $form->fields = json_decode($form->form_fields, true); if (!$form->fields['fields']) { return ''; } $form->settings = json_decode($formSettings->value, true); if ($form->status == 'unpublished') { global $wp_query; $wp_query->set_404(); status_header(404); nocache_headers(); include(get_query_template('404')); exit(); } $metaSettings = $this->getMetaSettings($formId); $shareKey = ArrayHelper::get($metaSettings, 'share_key'); if ($shareKey) { if ($providedKey != $shareKey && !Acl::hasAnyFormPermission($formId)) { return ''; } } $isRenderable = apply_filters('fluentform/is_form_renderable', [ 'status' => true, 'message' => '', ], $form); if (is_array($isRenderable) && !$isRenderable['status'] && !Acl::hasAnyFormPermission($formId)) { echo wp_kses_post("
" . $isRenderable['message'] . "
"); exit(200); } /* This filter is deprecated and will be removed soon */ $form = wpFluentForm()->applyFilters('fluentform_rendering_form', $form); $form = wpFluentForm()->applyFilters('fluentform/rendering_form', $form); $form = Converter::convert($form); $this->enqueueScripts(); $formSettings = wpFluent() ->table('fluentform_form_meta') ->where('form_id', $form->id) ->where('meta_key', 'formSettings') ->first(); if (!$formSettings) { return ''; } $form->settings = json_decode($formSettings->value, true); $submitCss = $this->getSubmitBttnStyle($form); $designSettings = $this->getDesignSettings($formId); wp_localize_script('fluent_forms_conversational_form', 'fluent_forms_global_var', [ 'fluent_forms_admin_nonce' => wp_create_nonce('fluent_forms_admin_nonce'), 'ajaxurl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce(), 'form' => $this->getLocalizedForm($form), 'form_id' => $form->id, 'assetBaseUrl' => FLUENT_CONVERSATIONAL_FORM_DIR_URL . 'public', 'i18n' => $metaSettings['i18n'], 'design' => $designSettings, 'hasPro' => defined('FLUENTFORMPRO'), 'extra_inputs' => $this->getExtraHiddenInputs($formId), 'uploading_txt' => __('Uploading', 'fluentform'), 'upload_completed_txt' => __('100% Completed', 'fluentform'), 'paymentConfig' => $this->getPaymentConfig($form), 'date_i18n' => \FluentForm\App\Modules\Component\Component::getDatei18n(), 'rest' => Helper::getRestInfo(), 'file_delete_nonce' => wp_create_nonce('fluentform_file_delete') ]); $hasSaveProgressButton = false; $saveProgressButton = []; foreach ($form->fields['fields'] as $item) { if (isset($item['element']) && $item['element'] === 'save_progress_button') { $hasSaveProgressButton = true; $saveProgressButton = $item; } } if ($hasSaveProgressButton && $saveProgressButton) { $this->localizeSaveProgressButton($saveProgressButton, $formId); } $this->printLoadedScripts(); $isRenderable = [ 'status' => true, 'message' => '', ]; /* This filter is deprecated and will be removed soon */ $isRenderable = apply_filters('fluentform_is_form_renderable', $isRenderable, $form); $isRenderable = apply_filters('fluentform/is_form_renderable', $isRenderable, $form); if (is_array($isRenderable) && !$isRenderable['status']) { if (!Acl::hasAnyFormPermission($form->id)) { echo wp_kses_post("

" . $isRenderable['message'] . '

'); exit(); } } /* This filter is deprecated and will be removed soon */ $status = apply_filters('fluentform-disabled_analytics', true); if (!apply_filters('fluentform/disabled_analytics', $status)) { if (!Acl::hasAnyFormPermission($form->id)) { (new \FluentForm\App\Services\Analytics\AnalyticsService())->store($form->id); } } wpFluentForm('view')->render('public.conversational-form', [ 'generated_css' => $this->getGeneratedCss($formId), 'design' => $designSettings, 'submit_css' => $submitCss, 'form_id' => $formId, 'meta' => $metaSettings, 'form' => $form, ]); exit(200); } /** * Enqueue proper stylesheet based on rtl & JS script. */ private function enqueueScripts() { $cssFileName = 'conversationalForm'; if (is_rtl()) { $cssFileName .= '-rtl'; } wp_enqueue_style( 'fluent_forms_conversational_form', FLUENT_CONVERSATIONAL_FORM_DIR_URL . 'public/css/' . $cssFileName . '.css', [], FLUENTFORM_VERSION ); wp_enqueue_script( 'fluent_forms_conversational_form', FLUENT_CONVERSATIONAL_FORM_DIR_URL . 'public/js/conversationalForm.js', [], FLUENTFORM_VERSION, true ); } /** * Get the payment configuration of this form. * * @param $form */ private function getPaymentConfig($form) { $paymentConfig = null; if ($form->has_payment) { $publishableKeyStripe = StripeSettings::getPublishableKey($form->id); $publishableKeyStripe = apply_filters_deprecated( 'fluentform-payment_stripe_publishable_key', [ $publishableKeyStripe, $form->id ], FLUENTFORM_FRAMEWORK_UPGRADE, 'fluentform/payment_stripe_publishable_key', 'Use fluentform/payment_stripe_publishable_key instead of fluentform-payment_stripe_publishable_key.' ); $publishableKey = apply_filters( 'fluentform/payment_stripe_publishable_key', $publishableKeyStripe, $form->id ); $paymentConfig = [ 'currency_settings' => PaymentHelper::getCurrencyConfig($form->id), 'stripe' => [ 'publishable_key' => $publishableKey, 'inlineConfig' => PaymentHelper::getStripeInlineConfig($form->id), ], 'stripe_app_info' => [ 'name' => 'Fluent Forms', 'version' => FLUENTFORM_VERSION, 'url' => site_url(), 'partner_id' => 'pp_partner_FN62GfRLM2Kx5d', ], 'i18n' => [ 'item' => __('Item', 'fluentform'), 'price' => __('Price', 'fluentform'), 'qty' => __('Qty', 'fluentform'), 'line_total' => __('Line Total', 'fluentform'), 'total' => __('Total', 'fluentform'), 'not_found' => __('No payment item selected yet', 'fluentform'), 'discount:' => __('Discount:', 'fluentform'), 'processing_text' => __('Processing payment. Please wait...', 'fluentform'), 'confirming_text' => __('Confirming payment. Please wait...', 'fluentform'), ], ]; $paymentConfig['currency_settings']['currency_symbol'] = \html_entity_decode($paymentConfig['currency_settings']['currency_sign']); } return $paymentConfig; } protected function getAsteriskPlacement($formId) { $asteriskPlacement = 'asterisk-right'; $formSettings = wpFluent() ->table('fluentform_form_meta') ->where('form_id', $formId) ->where('meta_key', 'formSettings') ->first(); if (!$formSettings) { return ''; } $formSettings = json_decode($formSettings->value, true); if (isset($formSettings['layout']['asteriskPlacement'])) { $asteriskPlacement = $formSettings['layout']['asteriskPlacement']; } return $asteriskPlacement; } private function getLocalizedForm($form) { return [ 'id' => $form->id, 'questions' => $form->questions, 'image_preloads' => $form->image_preloads, 'submit_button' => $form->submit_button, 'hasPayment' => (bool)$form->has_payment, 'hasCalculation' => (bool)$form->hasCalculation, 'reCaptcha' => $form->reCaptcha, 'hCaptcha' => $form->hCaptcha, 'turnstile' => $form->turnstile, 'has_per_step_save' => ArrayHelper::get($form->settings, 'conv_form_per_step_save', false), 'has_resume_from_last_step' => ArrayHelper::get($form->settings, 'conv_form_resume_from_last_step', false), 'has_save_link' => $form->save_state?? false, 'has_save_and_resume_button'=> $form->hasSaveAndResumeButton ?? false, 'step_completed' => $form->stepCompleted ?? 0 ]; } public function localizeSaveProgressButton($field, $formId) { $vars = apply_filters('fluentform/save_progress_vars', [ 'ajaxurl' => admin_url('admin-ajax.php'), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized in getFrontendFacingUrl() 'source_url' => Helper::getFrontendFacingUrl($_SERVER['REQUEST_URI']), 'form_id' => $formId, 'nonce' => wp_create_nonce(), 'copy_button' => fluentFormMix('img/copy.svg'), 'copy_success_button' => fluentFormMix('img/check.svg'), 'email_button' => fluentFormMix('img/email.svg'), 'email_placeholder_str' => __('Your Email Here', 'fluentform'), 'email_resume_link_enabled' => false, 'save_progress_btn_name' => ArrayHelper::get($field, 'attributes.name'), ]); if (ArrayHelper::get($field, 'settings.email_resume_link_enabled')) { $vars['email_resume_link_enabled'] = true; } wp_localize_script('fluent_forms_conversational_form', 'form_state_save_vars', $vars); } }