File "Converter.php"
Full Path: /home/romayxjt/public_html/wp-content/plugins/fluentform/app/Services/FluentConversational/Classes/Converter/Converter.php
File size: 56.11 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace FluentForm\App\Services\FluentConversational\Classes\Converter;
use FluentForm\App\Helpers\Helper;
use FluentForm\App\Modules\Payments\PaymentHelper;
use FluentForm\Framework\Helpers\ArrayHelper;
use FluentForm\App\Modules\Component\Component;
use FluentForm\App\Services\FormBuilder\Components\DateTime;
use FluentForm\App\Modules\Form\FormFieldsParser;
class Converter
{
public static function convert($form)
{
$fields = $form->fields['fields'];
$form->submit_button = $form->fields['submitButton'];
$form->reCaptcha = false;
$form->hCaptcha = false;
$form->turnstile = false;
$form->hasCalculation = false;
$questions = [];
$imagePreloads = [];
$allowedFields = static::fieldTypes();
$hasSaveAndResume = static::hasSaveAndResume($form);
$saveAndResumeData = [];
if ($hasSaveAndResume) {
$saveAndResumeData = static::getSaveAndResumeData($form);
$form->stepCompleted = intval(ArrayHelper::get($saveAndResumeData, 'step_completed', 0));
}
foreach ($fields as $field) {
$field = apply_filters_deprecated('fluentform_rendering_field_data_' . $field['element'],
[
$field,
$form
],
FLUENTFORM_FRAMEWORK_UPGRADE,
'fluentform/rendering_field_data_' . $field['element'],
'Use fluentform/rendering_field_data_' . $field['element'] . ' instead of fluentform_rendering_field_data_' . $field['element']
);
$field = apply_filters('fluentform/rendering_field_data_' . $field['element'], $field, $form);
$validationsRules = self::resolveValidationsRules($field, $form);
$question = static::buildBaseQuestion($field, $validationsRules, $form);
if (!$hasSaveAndResume && $answer = self::setDefaultValue(ArrayHelper::get($field, 'attributes.value'), $field, $form)) {
$question['answer'] = $answer;
}
if ($hasSaveAndResume && $saveAndResumeData) {
$response = ArrayHelper::get($saveAndResumeData, 'response');
$questionId = ArrayHelper::get($question, 'id');
// Special handling for section breaks and custom HTML
if (ArrayHelper::get($field, 'element') == 'section_break' || ArrayHelper::get($field, 'element') == 'custom_html') {
$question['answered'] = true;
$question['answer'] = 'section_viewed';
} else {
$value = $questionId ? ArrayHelper::get($response, $questionId) : null;
if (!empty($value)) {
if (ArrayHelper::get($field, 'element') == 'input_file') {
$files = ArrayHelper::get($response, $questionId);
foreach ($files as $file) {
$question['answer'][] = ArrayHelper::get($file, 'data_src');
}
} elseif (
ArrayHelper::get($field, 'element') == 'rangeslider' ||
ArrayHelper::get($field, 'element') == 'subscription_payment_component'
) {
$question['answer'] = +$value;
} else {
$question['answer'] = $value;
}
}
}
}
if ('default' != ArrayHelper::get($question, 'style_pref.layout')) {
$media = ArrayHelper::get($question, 'style_pref.media');
if ($media) {
$imagePreloads[] = $media;
}
}
if ('address' === $field['element']) {
if ($order = ArrayHelper::get($field, 'settings.field_order')) {
$order = array_values(array_column($order, 'value'));
$fields = ArrayHelper::get($field, 'fields');
$field['fields'] = array_merge(array_flip($order), $fields);
}
$googleAutoComplete = 'yes' === ArrayHelper::get($field, 'settings.enable_g_autocomplete');
if (defined('FLUENTFORMPRO') && $googleAutoComplete) {
$question['ff_map_autocomplete'] = true;
$question['ff_with_g_map'] = 'yes' == ArrayHelper::get($field, 'settings.enable_g_map');
$question['ff_with_auto_locate'] = ArrayHelper::get($field, 'settings.enable_auto_locate', false);
$question['GmapApiKey'] = apply_filters('fluentform/conversational_form_address_gmap_api_key', '');
}
foreach ($field['fields'] as $item) {
if ($item['settings']['visible']) {
$itemName = ArrayHelper::get($item, 'attributes.name');
if ($parentName = ArrayHelper::get($question, 'name')) {
$itemName = $parentName . '.' . $itemName;
}
$validationsRules = self::resolveValidationsRules($item, $form, $itemName);
$itemQuestion = [
'title' => ArrayHelper::get($item, 'settings.label'),
'container_class' => ArrayHelper::get($item, 'settings.container_class'),
'required' => ArrayHelper::get($validationsRules, 'required.value'),
'requiredMsg' => ArrayHelper::get($validationsRules, 'required.message'),
'errorMessage' => ArrayHelper::get($validationsRules, 'required.message'),
'validationRules' => $validationsRules,
'conditional_logics' => self::parseConditionalLogic($item),
];
if ('select_country' === $item['element']) {
$countryComponent = new \FluentForm\App\Services\FormBuilder\Components\SelectCountry();
$item = $countryComponent->loadCountries($item);
$activeList = ArrayHelper::get($item, 'settings.country_list.active_list');
if ('priority_based' == $activeList) {
$selectCountries = ArrayHelper::get($item, 'settings.country_list.priority_based', []);
$priorityCountries = $countryComponent->getSelectedCountries($selectCountries);
$item['options'] = array_merge($priorityCountries, $item['options']);
}
if ('visible_list' === $activeList && $googleAutoComplete) {
$restrictionCountries = (array) ArrayHelper::get($item, 'attributes.value', []);
$restrictionCountries = array_unique(
array_merge(
$restrictionCountries,
ArrayHelper::get($item, 'settings.country_list.visible_list', [])
)
);
$question['autocomplete_restrictions'] = array_filter($restrictionCountries);
}
$options = [];
$countries = $item['options'];
foreach ($countries as $key => $value) {
$options[] = [
'label' => $value,
'value' => $key,
];
}
$item['type'] = 'FlowFormTextType';
$item['options'] = $options;
}
if ($itemQuestion['required']) {
$question['requiredFields'][] = [
"name" => ArrayHelper::get($item, 'attributes.name', ''),
'requiredMessage' => ArrayHelper::get($itemQuestion, 'requiredMsg')
];
$question['required'] = true;
}
if (!$hasSaveAndResume) {
$item['attributes']['value'] = self::setDefaultValue(ArrayHelper::get($item, 'attributes.value', ''), $item, $form);;
}
$question['fields'][] = wp_parse_args($itemQuestion, $item);
}
}
} elseif ('input_name' === $field['element']) {
foreach ($field['fields'] as $item) {
if ($item['settings']['visible']) {
$itemName = ArrayHelper::get($item, 'attributes.name');
if ($parentName = ArrayHelper::get($question, 'name')) {
$itemName = $parentName . '.' . $itemName;
}
$validationsRules = self::resolveValidationsRules($item, $form, $itemName);
$itemQuestion = [
'title' => ArrayHelper::get($item, 'settings.label'),
'container_class' => ArrayHelper::get($item, 'settings.container_class'),
'required' => ArrayHelper::get($validationsRules, 'required.value'),
'requiredMsg' => ArrayHelper::get($validationsRules, 'required.message'),
'errorMessage' => ArrayHelper::get($validationsRules, 'required.message'),
'validationRules' => $validationsRules,
'conditional_logics' => self::parseConditionalLogic($item),
];
if ($itemQuestion['required']) {
$question['requiredFields'][] = [
"name" => ArrayHelper::get($item, 'attributes.name', ''),
'requiredMessage' => ArrayHelper::get($itemQuestion, 'requiredMsg', '')
];
$question['required'] = true;
}
$item['attributes']['value'] = (new Component(wpFluentForm()))->replaceEditorSmartCodes(ArrayHelper::get($item, 'attributes.value'), $form);
$question['fields'][] = wp_parse_args($itemQuestion, $item);
}
}
} elseif ('input_text' === $field['element']) {
$mask = ArrayHelper::get($field, 'settings.temp_mask');
$mask = 'custom' === $mask ? ArrayHelper::get($field, 'attributes.data-mask') : $mask;
if ($mask) {
$question['mask'] = $mask;
}
} elseif ('welcome_screen' === $field['element']) {
$question['settings'] = ArrayHelper::get($field, 'settings', []);
$question['subtitle'] = ArrayHelper::get($field, 'settings.description');
$question['required'] = false;
// $question['css'] = (new \FluentConversational\Form)->getSubmitBttnStyle($field);
} elseif ('select' === $field['element']) {
$question['options'] = self::getAdvancedOptions($field);
$question['placeholder'] = ArrayHelper::get($field, 'settings.placeholder', null);
$question['searchable'] = ArrayHelper::get($field, 'settings.enable_select_2');
$isMultiple = ArrayHelper::get($field, 'attributes.multiple', false);
if ($isMultiple) {
$question['multiple'] = true;
$question['placeholder'] = ArrayHelper::get($field, 'attributes.placeholder', false);
$question['max_selection'] = ArrayHelper::get($field, 'settings.max_selection');
$question['max_selection'] = $question['max_selection'] ? intval($question['max_selection']) : 0;
}
} elseif ('select_country' === $field['element']) {
$countryComponent = new \FluentForm\App\Services\FormBuilder\Components\SelectCountry();
$field = $countryComponent->loadCountries($field);
$activeList = ArrayHelper::get($field, 'settings.country_list.active_list');
if ('priority_based' == $activeList) {
$selectCountries = ArrayHelper::get($field, 'settings.country_list.priority_based', []);
$priorityCountries = $countryComponent->getSelectedCountries($selectCountries);
// @todo : add opt group in conversation js
$question['has_opt_grp'] = true;
$primaryListLabel = ArrayHelper::get($field, 'settings.primary_label');
$otherListLabel = ArrayHelper::get($field, 'settings.other_label');
$field['options'] = array_merge($priorityCountries, $field['options']);
}
$options = [];
$countries = $field['options'];
foreach ($countries as $key => $value) {
$options[] = [
'label' => $value,
'value' => $key,
];
}
$question['options'] = $options;
$question['placeholder'] = ArrayHelper::get($field, 'attributes.placeholder', null);
$question['searchable'] = ArrayHelper::get($field, 'settings.enable_select_2');
} elseif ('dynamic_field' === $field['element']) {
$dynamicFetchValue = 'yes' == ArrayHelper::get($field, 'settings.dynamic_fetch');
if ($dynamicFetchValue) {
$field = apply_filters('fluentform/dynamic_field_re_fetch_result_and_resolve_value', $field);
$question['answer'] = ArrayHelper::get($field, 'attributes.value');
}
$type = ArrayHelper::get($field, 'settings.field_type', 'select');
if (in_array($type, ['checkbox', 'radio'])) {
$question['type'] = 'FlowFormMultipleChoiceType';
$question['options'] = self::getAdvancedOptions($field);
if ('checkbox' == $type) {
$question['multiple'] = true;
}
} elseif (in_array($type, ['select', 'multi_select'])) {
$question['type'] = 'FlowFormDropdownType';
$question['options'] = self::getAdvancedOptions($field);
$question['searchable'] = ArrayHelper::get($field, 'settings.enable_select_2');
$question['multiple'] = ArrayHelper::isTrue($field, 'attributes.multiple');
} else {
continue;
}
$question['nextStepOnAnswer'] = true;
} elseif ('input_checkbox' === $field['element']) {
$question['options'] = self::getAdvancedOptions($field);
$question['multiple'] = true;
$question = static::hasPictureMode($field, $question);
} elseif ('input_radio' === $field['element']) {
$question['options'] = self::getAdvancedOptions($field);
$question['nextStepOnAnswer'] = true;
$question = static::hasPictureMode($field, $question);
} elseif ('custom_html' === $field['element']) {
$question['content'] = ArrayHelper::get($field, 'settings.html_codes', '');
} elseif ('section_break' === $field['element']) {
$question['content'] = ArrayHelper::get($field, 'settings.description', '');
$question['contentAlign'] = ArrayHelper::get($field, 'settings.align', '');
} elseif ('phone' === $field['element']) {
if (defined('FLUENTFORMPRO')) {
$question['phone_settings'] = self::getPhoneFieldSettings($field, $form);
if ($question['phone_settings']['enabled']) {
$cssSource = FLUENTFORMPRO_DIR_URL . 'public/libs/intl-tel-input/css/intlTelInput.min.css';
if (is_rtl()) {
$cssSource = FLUENTFORMPRO_DIR_URL . 'public/libs/intl-tel-input/css/intlTelInput-rtl.min.css';
}
wp_enqueue_style('intlTelInput', $cssSource, [], '18.1.1');
wp_enqueue_script('intlTelInputUtils', FLUENTFORMPRO_DIR_URL . 'public/libs/intl-tel-input/js/utils.js', [], '18.1.1', true);
wp_enqueue_script('intlTelInput', FLUENTFORMPRO_DIR_URL . 'public/libs/intl-tel-input/js/intlTelInput.min.js', [], '18.1.1', true);
}
}
} elseif ('input_number' === $field['element']) {
$question['min'] = ArrayHelper::get($field, 'settings.validation_rules.min.value');
$question['max'] = ArrayHelper::get($field, 'settings.validation_rules.max.value');
$question['min'] = is_numeric($question['min']) ? $question['min'] : null;
$question['max'] = is_numeric($question['max']) ? $question['max'] : null;
$question['is_calculable'] = true;
if (!$form->hasCalculation) {
$form->hasCalculation = static::hasFormula($question);
}
do_action_deprecated(
'ff_rendering_calculation_form',
[
$form,
$field
],
FLUENTFORM_FRAMEWORK_UPGRADE,
'fluentform/rendering_calculation_form',
'Use fluentform/rendering_calculation_form instead of ff_rendering_calculation_form'
);
do_action('fluentform/rendering_calculation_form', $form, $field);
} elseif (in_array($field['element'], ['terms_and_condition', 'gdpr_agreement'])) {
$question['options'] = [
[
'label' => ArrayHelper::get($field, 'settings.tc_agree_text', 'I accept'),
'value' => 'on',
],
];
if ('terms_and_condition' === $field['element']) {
$question['options'][] = [
'label' => ArrayHelper::get($field, 'settings.tc_dis_agree_text', 'I don\'t accept'),
'value' => 'off',
];
}
$question['nextStepOnAnswer'] = true;
$question['title'] = ArrayHelper::get($field, 'settings.tnc_html');
if ('gdpr_agreement' === $field['element']) {
$question['required'] = true;
}
} elseif ('ratings' === $field['element']) {
$question['show_text'] = ArrayHelper::get($field, 'settings.show_text');
$question['rateOptions'] = ArrayHelper::get($field, 'options', []);
$question['nextStepOnAnswer'] = true;
} elseif ('input_date' === $field['element']) {
$app = wpFluentForm();
$dateField = new DateTime();
wp_enqueue_style('flatpickr', fluentFormMix('libs/flatpickr/flatpickr.min.css'));
wp_enqueue_script('flatpickr', fluentFormMix('libs/flatpickr/flatpickr.min.js'), [], false, true);
$question['dateConfig'] = json_decode($dateField->getDateFormatConfigJSON($field['settings'], $form));
$question['dateCustomConfig'] = $dateField->getCustomConfig($field['settings']);
} elseif (in_array($field['element'], ['input_image', 'input_file'])) {
$question['multiple'] = true;
$maxFileCount = ArrayHelper::get($field, 'settings.validation_rules.max_file_count');
$maxFileSize = ArrayHelper::get($field, 'settings.validation_rules.max_file_size');
if ('input_image' === $field['element']) {
$allowedFieldTypes = ArrayHelper::get($field, 'settings.validation_rules.allowed_image_types.value');
$question['validationRules']['allowed_file_types'] = $question['validationRules']['allowed_image_types'];
} else {
$allowedFieldTypes = ArrayHelper::get($field, 'settings.validation_rules.allowed_file_types.value');
}
if ($maxFileCount) {
$question['max'] = $maxFileCount['value'];
}
if ($maxFileSize) {
$question['maxSize'] = $maxFileSize['value'];
}
if ($allowedFieldTypes) {
$question['accept'] = implode('|', $allowedFieldTypes);
}
} elseif ('tabular_grid' === $field['element']) {
$question['grid_columns'] = $field['settings']['grid_columns'];
$question['grid_rows'] = $field['settings']['grid_rows'];
$question['selected_grids'] = $field['settings']['selected_grids'];
$question['multiple'] = 'checkbox' === $field['settings']['tabular_field_type'];
if ($field['settings']['selected_grids']) {
$rowValues = array_keys($question['grid_rows']);
$colValues = array_keys($question['grid_columns']);
foreach ($field['settings']['selected_grids'] as $selected) {
if (in_array($selected, $rowValues)) {
$question['answer'][$selected] = $colValues;
} else {
foreach ($rowValues as $rowValue) {
if ($question['multiple']) {
$question['answer'][$rowValue][] = $selected;
} else {
$question['answer'][$rowValue] = $selected;
}
}
}
}
}
$question['requiredPerRow'] = ArrayHelper::get($field, 'settings.validation_rules.required.per_row');
} elseif ('rangeslider' === $field['element']) {
if (!ArrayHelper::exists($question, 'answer')) {
if ($field['attributes']['value'] == '') {
$question['answer'] = 0;
} else {
$question['answer'] = +$field['attributes']['value'];
}
}
$question['min'] = intval($field['attributes']['min']);
$question['max'] = intval($field['attributes']['max']);
if ($step = ArrayHelper::get($field, 'settings.number_step')) {
$question['step'] = intval($step);
} else {
$question['step'] = 1;
}
$question['is_calculable'] = true;
$question['type'] = 'FlowFormRangesliderType';
} elseif ('save_progress_button' === $field['element']) {
// Add the save progress button data to the previous question
if ($questions && count($questions) > 0) {
$lastQuestion = &$questions[count($questions) - 1];
$question['id'] = ArrayHelper::get($field, 'attributes.name');
$question['parent_id'] = $lastQuestion['id'];
$question['title'] = ArrayHelper::get($field, 'editor_options.title');
$question['settings'] = ArrayHelper::get($field, 'settings');
$question['counter'] = count($questions) - 1;
$lastQuestion['has_save_and_resume_button'] = true;
$lastQuestion['save_and_resume_button'] = $question;
$form->hasSaveAndResumeButton = true;
}
// Skip Save Progress Button as a separate question
continue;
} elseif ('multi_payment_component' === $field['element']) {
$type = $field['attributes']['type'];
if ('single' == $type) {
$question['priceLabel'] = $field['settings']['price_label'];
} else {
$question['nextStepOnAnswer'] = true;
if ('radio' == $type || 'checkbox' == $type) {
$question['paymentType'] = 'MultipleChoiceType';
$question['type'] = 'FlowFormMultipleChoiceType';
$question = static::hasPictureMode($field, $question);
if ('checkbox' == $type) {
$question['multiple'] = true;
}
} else {
$question['paymentType'] = 'DropdownType';
$question['type'] = 'FlowFormDropdownType';
}
$question['options'] = ArrayHelper::get($field, 'settings.pricing_options');
}
$question['is_payment_field'] = true;
$question['is_calculable'] = true;
} elseif ('subscription_payment_component' === $field['element']) {
$question['is_payment_field'] = true;
$question['is_subscription_field'] = true;
if (!$hasSaveAndResume) {
$question['answer'] = null;
}
$type = $field['attributes']['type'];
$question['subscriptionFieldType'] = $type;
$currency = PaymentHelper::getFormCurrency($form->id);
foreach ($field['settings']['subscription_options'] as $index => &$option) {
$hasCustomPayment = false;
if (array_key_exists('user_input', $option) && 'yes' == $option['user_input']) {
$hasCustomPayment = true;
$option['subscription_amount'] = 0;
if (array_key_exists('user_input_default_value', $option)) {
$option['subscription_amount'] = $option['user_input_default_value'];
}
}
$paymentSummaryText = PaymentHelper::getPaymentSummaryText($option, $form->id, $currency, false);
$planValue = 'single' == $type ? $option['subscription_amount'] : $index;
$field['plans'][] = [
'label' => $option['name'],
'value' => $planValue,
'sub' => strip_tags($paymentSummaryText),
'subscription_amount' => $planValue,
];
$option['sub'] = strip_tags($paymentSummaryText);
if ('yes' == $option['is_default'] && !$hasSaveAndResume) {
$question['answer'] = $index;
}
if ($hasCustomPayment) {
$option['customInput'] = $question['name'] . '_custom_' . $index;
if ($hasSaveAndResume && $saveAndResumeData) {
if ($customPayment = ArrayHelper::get($saveAndResumeData, 'response.' . $option['customInput'])) {
$question['customPayment'] = $customPayment;
}
} else {
$question['customPayment'] = $option['subscription_amount'];
}
}
}
$question['plans'] = $field['settings']['subscription_options'];
if ('single' != $type) {
$question['options'] = $field['plans'];
$question['subscriptionFieldType'] = 'radio' == $field['settings']['selection_type'] ? 'FlowFormMultipleChoiceType' : 'FlowFormDropdownType';
$question['nextStepOnAnswer'] = true;
}
} elseif ('custom_payment_component' === $field['element']) {
$question['type'] = 'FlowFormNumberType';
$question['min'] = ArrayHelper::get($field, 'settings.validation_rules.min.value');
$question['max'] = ArrayHelper::get($field, 'settings.validation_rules.max.value');
$question['min'] = is_numeric($question['min']) ? $question['min'] : null;
$question['max'] = is_numeric($question['max']) ? $question['max'] : null;
$question['is_payment_field'] = true;
$question['is_calculable'] = true;
if (!$form->hasCalculation) {
$form->hasCalculation = static::hasFormula($question);
}
do_action_deprecated(
'ff_rendering_calculation_form',
[
$form,
$field
],
FLUENTFORM_FRAMEWORK_UPGRADE,
'fluentform/rendering_calculation_form',
'Use fluentform/rendering_calculation_form instead of ff_rendering_calculation_form'
);
do_action('fluentform/rendering_calculation_form', $form, $field);
} elseif ('item_quantity_component' === $field['element']) {
$question['type'] = $allowedFields['input_number'];
$question['targetProduct'] = $field['settings']['target_product'];
$question['min'] = ArrayHelper::get($field, 'settings.validation_rules.min.value');
$question['max'] = ArrayHelper::get($field, 'settings.validation_rules.max.value');
$question['min'] = is_numeric($question['min']) ? $question['min'] : null;
$question['max'] = is_numeric($question['max']) ? $question['max'] : null;
$question['step'] = 1;
$question['stepErrorMsg'] = __('Please enter a valid value. The two nearest valid values are {lower_value} and {upper_value}', 'fluentform');
} elseif ('payment_method' === $field['element']) {
$question['nextStepOnAnswer'] = true;
$question['options'] = [];
$question['paymentMethods'] = [];
foreach ($field['settings']['payment_methods'] as $methodName => $paymentMethod) {
if ('yes' === $paymentMethod['enabled']) {
$question['options'][] = [
'label' => $paymentMethod['settings']['option_label']['value'],
'value' => $paymentMethod['method_value'],
];
$question['paymentMethods'][$methodName] = $paymentMethod;
do_action_deprecated(
'fluentform_rendering_payment_method_' . $methodName,
[
$paymentMethod,
$field,
$form
],
FLUENTFORM_FRAMEWORK_UPGRADE,
'fluentform/rendering_payment_method_' . $methodName,
'Use fluentform/rendering_payment_method_' . $methodName . ' instead of fluentform_rendering_payment_method_' . $methodName
);
do_action(
'fluentform/rendering_payment_method_' . $methodName,
$paymentMethod,
$field,
$form
);
}
}
} elseif ('payment_summary_component' === $field['element']) {
$question['title'] = __('Payment Summary', 'fluentform');
$question['emptyText'] = $field['settings']['cart_empty_text'];
} elseif ('recaptcha' === $field['element']) {
$reCaptchaConfig = get_option('_fluentform_reCaptcha_details');
$siteKey = ArrayHelper::get($reCaptchaConfig, 'siteKey');
if (! $siteKey) {
continue;
}
$question['siteKey'] = $siteKey;
$question['answer'] = '';
$apiVersion = ArrayHelper::get($reCaptchaConfig, 'api_version', 'v2_visible');
$apiVersion = 'v3_invisible' == $apiVersion ? 3 : 2;
$api = 'https://www.google.com/recaptcha/api.js';
$form->reCaptcha = [
'version' => $apiVersion,
'siteKey' => $siteKey,
];
if (3 === $apiVersion) {
$api .= '?render=' . $siteKey;
}
wp_enqueue_script(
'google-recaptcha',
$api,
[],
FLUENTFORM_VERSION,
true
);
if (3 === $apiVersion) {
continue;
}
} elseif (('hcaptcha' === $field['element'])) {
$hCaptchaConfig = get_option('_fluentform_hCaptcha_details');
$siteKey = ArrayHelper::get($hCaptchaConfig, 'siteKey');
if (! $siteKey) {
continue;
}
$question['siteKey'] = $siteKey;
$api = 'https://js.hcaptcha.com/1/api.js';
$form->hCaptcha = [
'siteKey' => $siteKey,
];
wp_enqueue_script(
'hcaptcha',
$api,
[],
FLUENTFORM_VERSION,
true
);
} elseif ('turnstile' === $field['element']) {
$turnstileConfig = get_option('_fluentform_turnstile_details');
$siteKey = ArrayHelper::get($turnstileConfig, 'siteKey');
$appearance = ArrayHelper::get($turnstileConfig, 'appearance', 'always');
$theme = ArrayHelper::get($turnstileConfig, 'theme', 'auto');
if (! $siteKey) {
continue;
}
$question['siteKey'] = $siteKey;
$question['appearance'] = $appearance;
$question['theme'] = $theme;
$form->turnstile = [
'siteKey' => $siteKey,
'appearance' => $appearance,
];
wp_enqueue_script(
'turnstile_conv',
'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit',
[],
FLUENTFORM_VERSION,
false
);
// for WP Rocket compatibility
wp_script_add_data('turnstile_conv', 'data-cfasync', 'false');
if ('interaction-only' === $appearance) {
continue;
}
} elseif ('payment_coupon' === $field['element']) {
if ($hasSaveAndResume && $saveAndResumeData) {
if ($coupons = ArrayHelper::get($saveAndResumeData, 'response.__ff_all_applied_coupons')) {
$question['answer'] = json_decode($coupons);
}
}
}
do_action('fluentform/conversational_question', $question, $field, $form);
if ($question['type']) {
$questions[] = $question;
}
if ('custom_submit_button' === $field['element']) {
$form->submit_button = $field;
}
}
$form->questions = $questions;
$form->image_preloads = $imagePreloads;
return $form;
}
public static function convertExistingForm($form)
{
$formFields = json_decode($form->form_fields, true);
$fields = $formFields['fields'];
$formattedFields = [];
if (is_array($fields) && ! empty($fields)) {
foreach ($fields as $field) {
$element = ArrayHelper::get($field, 'element');
$allowedFields = array_keys(static::fieldTypes());
if (!in_array($element, $allowedFields)) {
continue;
}
if (! ArrayHelper::exists($field, 'style_pref')) {
$field['style_pref'] = [
'layout' => 'default',
'media' => fluentFormGetRandomPhoto(),
'brightness' => 0,
'alt_text' => '',
'media_x_position' => 50,
'media_y_position' => 50,
];
}
$formattedFields[] = $field;
}
}
$formFields['fields'] = $formattedFields;
return json_encode($formFields);
}
private static function buildBaseQuestion($field, $validationsRules, $form)
{
return [
'id' => ArrayHelper::get($field, 'attributes.name'),
'name' => ArrayHelper::get($field, 'attributes.name'),
'title' => ArrayHelper::get($field, 'settings.label'),
'type' => ArrayHelper::get(static::fieldTypes(), $field['element']),
'ff_input_type' => ArrayHelper::get($field, 'element'),
'container_class' => ArrayHelper::get($field, 'settings.container_class'),
'placeholder' => ArrayHelper::get($field, 'attributes.placeholder'),
'maxLength' => ArrayHelper::get($field, 'attributes.maxlength'),
'required' => ArrayHelper::get($validationsRules, 'required.value'),
'requiredMsg' => ArrayHelper::get($validationsRules, 'required.message'),
'errorMessage' => ArrayHelper::get($validationsRules, 'required.message'),
'validationRules' => $validationsRules,
'tagline' => ArrayHelper::get($field, 'settings.help_message'),
'style_pref' => ArrayHelper::get($field, 'style_pref', [
'layout' => 'default',
'media' => '',
'brightness' => 0,
'alt_text' => '',
'media_x_position' => 50,
'media_y_position' => 50,
]),
'conditional_logics' => self::parseConditionalLogic($field),
'calculation_settings' => ArrayHelper::get($field, 'settings.calculation_settings'),
'is_calculable' => ArrayHelper::get($field, 'settings.calc_value_status', false),
'has_save_and_resume' => static::hasSaveAndResume($form)
];
}
public static function fieldTypes()
{
$fieldTypes = [
'input_url' => 'FlowFormUrlType',
'input_date' => 'FlowFormDateType',
'input_text' => 'FlowFormTextType',
'input_email' => 'FlowFormEmailType',
'input_hidden' => 'FlowFormHiddenType',
'input_number' => 'FlowFormNumberType',
'select' => 'FlowFormDropdownType',
'select_country' => 'FlowFormDropdownType',
'textarea' => 'FlowFormLongTextType',
'input_password' => 'FlowFormPasswordType',
'custom_html' => 'FlowFormSectionBreakType',
'section_break' => 'FlowFormSectionBreakType',
'welcome_screen' => 'FlowFormWelcomeScreenType',
'input_checkbox' => 'FlowFormMultipleChoiceType',
'input_radio' => 'FlowFormMultipleChoiceType',
'terms_and_condition' => 'FlowFormTermsAndConditionType',
'gdpr_agreement' => 'FlowFormTermsAndConditionType',
'MultiplePictureChoice' => 'FlowFormMultiplePictureChoiceType',
'recaptcha' => 'FlowFormReCaptchaType',
'hcaptcha' => 'FlowFormHCaptchaType',
'turnstile' => 'FlowFormTurnstileType',
'address' => 'FlowFormAddressType',
'input_name' => 'FlowFormNameType',
'ffc_custom' => 'FlowFormCustomType',
'payment_method' => 'FlowFormPaymentMethodType',
'multi_payment_component' => 'FlowFormPaymentType',
'custom_payment_component' => 'FlowFormPaymentType',
'item_quantity_component' => 'FlowFormPaymentType',
'payment_summary_component' => 'FlowFormPaymentSummaryType',
'subscription_payment_component' => 'FlowFormSubscriptionType',
];
if (Helper::hasPro()) {
$fieldTypes['phone'] = 'FlowFormPhoneType';
$fieldTypes['input_image'] = 'FlowFormFileType';
$fieldTypes['input_file'] = 'FlowFormFileType';
$fieldTypes['ratings'] = 'FlowFormRateType';
$fieldTypes['tabular_grid'] = 'FlowFormMatrixType';
$fieldTypes['payment_coupon'] = 'FlowFormCouponType';
$fieldTypes['quiz_score'] = 'FlowFormHiddenType';
$fieldTypes['rangeslider'] = 'FlowFormRangesliderType';
$fieldTypes['save_progress_button'] = 'FlowFormSaveAndResumeType';
$fieldTypes['dynamic_field'] = 'FlowFormDynamicFieldType';
}
return apply_filters('fluentform/conversational_field_types', $fieldTypes);
}
public static function hasPictureMode($field, $question)
{
$pictureMode = ArrayHelper::get($field, 'settings.enable_image_input');
if ($pictureMode) {
$question['type'] = static::fieldTypes()['MultiplePictureChoice'];
}
return $question;
}
public static function hex2rgb($color, $opacity = 0.3)
{
if (! $color) {
return;
}
$rgbValues = [$r, $g, $b] = array_map(
function ($c) {
return hexdec(str_pad($c, 2, $c));
},
str_split(ltrim($color, '#'), strlen($color) > 4 ? 2 : 1)
);
$rgbValues[3] = $opacity;
$formattedValues = implode(',', $rgbValues);
return "rgb({$formattedValues})";
}
public static function getPhoneFieldSettings($data, $form)
{
$geoLocate = 'yes' == ArrayHelper::get($data, 'settings.auto_select_country');
// todo:: remove the 'with_extended_validation' check in future.
$enabled = ArrayHelper::get($data, 'settings.validation_rules.valid_phone_number.value');
if (! $enabled) {
$enabled = 'with_extended_validation' == ArrayHelper::get($data, 'settings.int_tel_number');
}
$itlOptions = [
'separateDialCode' => false,
'nationalMode' => true,
'autoPlaceholder' => 'aggressive',
'formatOnDisplay' => true,
];
if ($geoLocate) {
$itlOptions['initialCountry'] = 'auto';
} else {
$itlOptions['initialCountry'] = ArrayHelper::get($data, 'settings.default_country', '');
$activeList = ArrayHelper::get($data, 'settings.phone_country_list.active_list');
if ('priority_based' == $activeList) {
$selectCountries = ArrayHelper::get($data, 'settings.phone_country_list.priority_based', []);
$priorityCountries = self::getSelectedCountries($selectCountries);
$itlOptions['preferredCountries'] = array_keys($priorityCountries);
} elseif ('visible_list' == $activeList) {
$onlyCountries = ArrayHelper::get($data, 'settings.phone_country_list.visible_list', []);
$itlOptions['onlyCountries'] = $onlyCountries;
} elseif ('hidden_list' == $activeList) {
$countries = self::loadCountries($data);
$itlOptions['onlyCountries'] = array_keys($countries);
}
}
$itlOptions = apply_filters_deprecated(
'fluentform_itl_options',
[
$itlOptions,
$data,
$form
],
FLUENTFORM_FRAMEWORK_UPGRADE,
'fluentform/itl_options',
'Use fluentform/itl_options instead of fluentform_itl_options'
);
$itlOptions = apply_filters('fluentform/itl_options', $itlOptions, $data, $form);
$itlOptions = json_encode($itlOptions);
$settings = get_option('_fluentform_global_form_settings');
$token = ArrayHelper::get($settings, 'misc.geo_provider_token');
$url = 'https://ipinfo.io';
if ($token) {
$url = 'https://ipinfo.io/?token=' . $token;
}
$url = apply_filters_deprecated(
'fluentform_ip_provider',
[
$url
],
FLUENTFORM_FRAMEWORK_UPGRADE,
'fluentform/ip_provider',
'Use fluentform/ip_provider instead of fluentform_ip_provider'
);
$ipProviderUrl = apply_filters('fluentform/ip_provider', $url);
return [
'enabled' => $enabled,
'itlOptions' => $itlOptions,
'ipLookupUrl' => ($geoLocate && $ipProviderUrl) ? $ipProviderUrl : false,
];
}
/**
* Load country list from file
*
* @param array $data
*
* @return array
*/
public static function loadCountries($data)
{
$data['options'] = [];
$activeList = ArrayHelper::get($data, 'settings.phone_country_list.active_list');
$countries = getFluentFormCountryList();
$filteredCountries = [];
if ('visible_list' == $activeList) {
$selectCountries = ArrayHelper::get($data, 'settings.phone_country_list.' . $activeList, []);
foreach ($selectCountries as $value) {
$filteredCountries[$value] = $countries[$value];
}
} elseif ('hidden_list' == $activeList || 'priority_based' == $activeList) {
$filteredCountries = $countries;
$selectCountries = ArrayHelper::get($data, 'settings.phone_country_list.' . $activeList, []);
foreach ($selectCountries as $value) {
unset($filteredCountries[$value]);
}
} else {
$filteredCountries = $countries;
}
return $filteredCountries;
}
public static function getSelectedCountries($keys = [])
{
$options = [];
$countries = getFluentFormCountryList();
foreach ($keys as $value) {
$options[$value] = $countries[$value];
}
return $options;
}
public static function setDefaultValue($value, $field, $form)
{
if ($dynamicValue = ArrayHelper::get($field, 'settings.dynamic_default_value')) {
$dynamicVal = (new Component(wpFluentForm()))->replaceEditorSmartCodes($dynamicValue, $form);
$element = $field['element'];
if ($dynamicVal && 'input_checkbox' == $element) {
$defaultValues = explode(',', $dynamicVal);
return array_map('trim', $defaultValues);
}
if ($dynamicVal) {
return $dynamicVal;
}
}
if (! $value) {
return $value;
}
if (is_string($value)) {
return (new Component(wpFluentForm()))->replaceEditorSmartCodes($value, $form);
}
return $value;
}
private static function parseConditionalLogic($field)
{
$logics = ArrayHelper::get($field, 'settings.conditional_logics', []);
if (! $logics || ! $logics['status']) {
return [];
}
$type = ArrayHelper::get($logics, 'type', '');
if ($type === 'group') {
return self::parseGroupConditionalLogic($logics);
} else {
return self::parseSimpleConditionalLogic($logics);
}
}
private static function parseSimpleConditionalLogic($logics)
{
$validConditions = self::parseConditions(ArrayHelper::get($logics, 'conditions'));
if (!$validConditions) {
return [];
}
$logics['conditions'] = $validConditions;
return $logics;
}
private static function parseGroupConditionalLogic($logics)
{
$validGroups = [];
$conditionGroups = ArrayHelper::get($logics, 'condition_groups', []);
foreach ($conditionGroups as $group) {
$validConditions = self::parseConditions(ArrayHelper::get($group, 'rules'));
if ($validConditions) {
$validGroups[] = [
'rules' => $validConditions,
];
}
}
if (!$validGroups) {
return [];
}
$logics['condition_groups'] = $validGroups;
return $logics;
}
private static function parseConditions($conditions)
{
if (!$conditions) {
return [];
}
return array_filter($conditions, function($condition) {
return !empty($condition['field']) && !empty($condition['operator']);
});
}
private static function getAdvancedOptions($field)
{
$options = ArrayHelper::get($field, 'settings.advanced_options', []);
if ($options && 'yes' == ArrayHelper::get($field, 'settings.randomize_options')) {
shuffle($options);
}
return $options;
}
private static function hasFormula($question)
{
return (bool) (
ArrayHelper::get($question, 'calculation_settings.status')
&& ArrayHelper::get($question, 'calculation_settings.formula')
);
}
private static function hasSaveAndResume($form)
{
if (!defined('FLUENTFORMPRO')){
return false;
}
if (!version_compare(FLUENTFORMPRO_VERSION,'5.1.13' ,'>=')){
return false;
}
$hasSaveProgressButton = FormFieldsParser::hasElement($form, 'save_progress_button');
$perStepSave = ArrayHelper::get($form->settings, 'conv_form_per_step_save');
if ($perStepSave || $hasSaveProgressButton) {
$saveAndResume = false;
$hash = '';
$form->save_state = false;
$key = isset($_GET['fluent_state']) ? sanitize_text_field($_GET['fluent_state']) : false;
if ($key) {
$hash = base64_decode($key);
$form->save_state = true;
} else {
$cookieName = 'fluentform_step_form_hash_' . $form->id;
$hash = ArrayHelper::get($_COOKIE, $cookieName, wp_generate_uuid4());
}
\FluentFormPro\classes\DraftSubmissionsManager::migrate();
$draftForm = wpFluent()->table('fluentform_draft_submissions')->where('hash', $hash)->first();
if ($draftForm) {
$saveAndResume = true;
}
return $saveAndResume;
}
return false;
}
/**
* @param array $field
* @param object $form
* @param string $fieldName
* @return array
*/
private static function resolveValidationsRules($field, $form, $fieldName = '')
{
$validationsRules = ArrayHelper::get($field, 'settings.validation_rules', []);
if ($validationsRules) {
if (!$fieldName) {
$fieldName = ArrayHelper::get($field, 'attributes.name');
}
foreach ($validationsRules as $ruleName => $rule) {
if (ArrayHelper::exists($rule, 'message')) {
if (ArrayHelper::isTrue($rule, 'global')) {
$rule['message'] = apply_filters('fluentform/get_global_message_' . $ruleName, $rule['message']);;
}
// Shortcode parse on validation message
$rule['message'] = Helper::shortCodeParseOnValidationMessage($rule['message'], $form, $fieldName);
$validationsRules[$ruleName]['message'] = apply_filters('fluentform/validation_message_' . $ruleName, $rule['message'], $field);
}
}
}
return $validationsRules;
}
private static function getSaveAndResumeData($form)
{
$draftForm = null;
$data = [];
$formId = $form->id;
$key = isset($_GET['fluent_state']) ? sanitize_text_field($_GET['fluent_state']) : false;
if ($key) {
$hash = base64_decode($key);
} else {
$cookieName = 'fluentform_step_form_hash_' . $formId;
$hash = ArrayHelper::get($_COOKIE, $cookieName, wp_generate_uuid4());
}
if ($hash) {
$draftForm = wpFluent()->table('fluentform_draft_submissions')
->where('hash', $hash)
->where('form_id', $formId)
->first();
} elseif (!$draftForm && $userId = get_current_user_id()) {
$draftForm = wpFluent()->table('fluentform_draft_submissions')
->where('user_id', $userId)
->where('form_id', $formId)
->first();
} else {
return $data;
}
if ($draftForm) {
$data['step_completed'] = (int)$draftForm->step_completed;
$data['response'] = json_decode($draftForm->response, true);
$fields = FormFieldsParser::getInputsByElementTypes($form, ['input_file', 'input_image']);
foreach ($fields as $name => $field) {
if ($urls = ArrayHelper::get($data['response'], $name)) {
foreach ($urls as $index => $url) {
$data['response'][$name][$index] = [
"data_src" => $url,
"url" => \FluentForm\App\Helpers\Helper::maybeDecryptUrl($url)
];
}
}
}
unset(
$data['response']['_wp_http_referer'],
$data['response']['__fluent_form_embded_post_id'],
$data['response']['_fluentform_' . $draftForm->form_id . '_fluentformnonce']
);
}
return $data;
}
}