getCurrentContact(true, true); if (!$subscriber) { return $noContactContent; } /** * Determine the preference form labels in FluentCRM. * * This filter allows modification of the labels used in the preference form. * * @since 2.5.95 * * @param array { * An associative array of labels. * * @type string $first_name Label for the first name field. * @type string $last_name Label for the last name field. * @type string $prefix Label for the title field. * @type string $email Label for the email field. * @type string $phone Label for the phone/mobile field. * @type string $dob Label for the date of birth field. * @type string $address_line_1 Label for the address line 1 field. * @type string $address_line_2 Label for the address line 2 field. * @type string $city Label for the city field. * @type string $state Label for the state field. * @type string $postal_code Label for the ZIP code field. * @type string $country Label for the country field. * @type string $update Label for the update info button. * @type string $address_heading Label for the address information section. * @type string $list_label Label for the mailing list groups section. * } */ $labels = apply_filters('fluent_crm/pref_labels', [ 'first_name' => __('First Name', 'fluent-crm'), 'last_name' => __('Last Name', 'fluent-crm'), 'prefix' => __('Title', 'fluent-crm'), 'email' => __('Email', 'fluent-crm'), 'phone' => __('Phone/Mobile', 'fluent-crm'), 'dob' => __('Date of Birth', 'fluent-crm'), 'address_line_1' => __('Address Line 1', 'fluent-crm'), 'address_line_2' => __('Address Line 2', 'fluent-crm'), 'city' => __('City', 'fluent-crm'), 'state' => __('State', 'fluent-crm'), 'postal_code' => __('ZIP Code', 'fluent-crm'), 'country' => __('Country', 'fluent-crm'), 'update' => __('Update info', 'fluent-crm'), 'address_heading' => __('Address Information', 'fluent-crm'), 'list_label' => __('Mailing List Groups', 'fluent-crm'), 'custom_fields' => __('Custom Fields', 'fluent-crm') ]); $formFields = $this->getFormFields($settings, $subscriber, $labels, false); $listOptions = []; $lists = Helper::getPublicLists(); if ($lists) { foreach ($lists as $list) { $listOptions[strval($list->id)] = $list->title; } $formattedLists = []; foreach ($subscriber->lists as $list) { $formattedLists[] = $list->id; } $formFields['lists'] = [ 'type' => 'checkboxes', 'name' => 'lists', 'container_class' => 'fc_inline_checkboxes', 'options' => $listOptions, 'value' => $formattedLists, 'id' => 'mailing_lists', 'label' => Arr::get($labels, 'list_label', 'Mailing List Groups'), ]; } /** * Determine the preference form fields against a subscriber or contact data in FluentCRM. * * This filter allows modification of the preference form fields before they are displayed. * * @since 2.5.95 * * @param array $formFields The current form fields. * @param object $subscriber The subscriber object. * @return array Modified form fields. */ $formFields = apply_filters('fluent_crm/pref_form_fields', $formFields, $subscriber); $formFields[] = [ 'type' => 'hidden', 'atts' => [ 'name' => 'action', 'value' => 'fluent_crm_account_form' ] ]; if (isset($_REQUEST['_fc_secure_hash'])) { $hash = sanitize_text_field($_REQUEST['_fc_secure_hash']); if($hash) { $formFields[] = [ 'type' => 'hidden', 'atts' => [ 'name' => '_fc_hash_secure', 'value' => $hash ] ]; } } wp_enqueue_style( 'fluentcrm_public_pref', fluentCrmMix('public/public_pref.css'), [], FLUENTCRM_PLUGIN_VERSION ); wp_enqueue_script('fluentcrm_public_pref', fluentCrmMix('public/public_pref.js'), ['jquery'], FLUENTCRM_PLUGIN_VERSION, true); wp_localize_script('fluentcrm_public_pref', 'fluentcrm_sub_pref', [ 'ajaxurl' => admin_url('admin-ajax.php') ]); return (string) fluentCrm('view')->make('external.pref_form', [ 'fields' => $formFields, 'submitBtn' => [ 'container_class' => 'fc_pref_submit', 'btn_text' => __('Update info', 'fluent-crm'), 'atts' => [ 'type' => 'submit', 'id' => 'fluentcrm_preferences_submit', 'class' => 'btn fc_pref_submit' ] ], 'subscriber' => $subscriber ]); } public function handleDynamicContentShortCode($atts, $text = '') { if(!$text) { return ''; } $defaults = [ 'hide_for_guest' => 'no' ]; $atts = shortcode_atts($defaults, $atts, 'fluentcrm_content'); $subscriber = FluentCrmApi('contacts')->getCurrentContact(true, true); if(!$subscriber) { if($atts['hide_for_guest'] == 'yes') { return ''; } return preg_replace_callback('/({{|##)+(.*?)(}}|##)/', function ($matches) { if(isset($matches[2])) { $token = $matches[2]; $tokens = explode('|', $token); if(isset($tokens[1])) { return $tokens[1]; } } return ''; }, $text); } return \FluentCrm\App\Services\Libs\Parser\Parser::parse($text, $subscriber); } public function handleAjax() { if (!isset($_POST['_fc_nonce']) || !wp_verify_nonce($_POST['_fc_nonce'], 'fluent_crm_account_form_fields')) { wp_send_json_error([ 'message' => __('Sorry, your nonce did not verify.', 'fluent-crm') ], 422); } $settings = Helper::getGlobalEmailSettings(); if (Arr::get($settings, 'pref_form') != 'yes' || empty(Arr::get($settings, 'pref_general'))) { wp_send_json_error([ 'message' => __('Sorry! You cannot update your profile.', 'fluent-crm') ], 422); } if (isset($_REQUEST['_fc_hash_secure']) && !is_user_logged_in()) { $hash = sanitize_text_field($_REQUEST['_fc_hash_secure']); if ($hash) { $_COOKIE['fc_hash_secure'] = $hash; } } $subscriber = FluentCrmApi('contacts')->getCurrentContact(false, true); if (!$subscriber) { wp_send_json_error([ 'message' => __('Sorry! You cannot update your profile.', 'fluent-crm') ], 422); } $validInputs = $this->getFormFields($settings, $subscriber, [], true); $validKeys = array_keys($validInputs); $validData = Arr::only($_REQUEST, $validKeys); if (empty($validData['email'])) { $validData['email'] = $subscriber->email; } $errors = []; foreach ($validInputs as $key => $input) { if (Arr::get($input, 'required') && empty($validData[$key])) { $errors[] = $key . ' is required'; } // Handle array values for multi-select and checkboxes if (isset($validData[$key]) && is_array($validData[$key])) { $validData[$key] = array_map('sanitize_text_field', $validData[$key]); } else { $validData[$key] = sanitize_text_field(Arr::get($validData, $key, '')); } } if (!empty($validData['date_of_birth']) && !$this->isValidDate($validData['date_of_birth'])) { $errors[] = 'date_of_birth'; } if ($errors) { wp_send_json_error([ 'message' => __('Please fill up all required fields', 'fluent-crm'), 'errors' => $errors, 'inputs' => $validData ], 422); } // Handle custom fields $enabledCustomFieldSlugs = Arr::get($settings, 'pref_custom', []); $allCustomFields = (new CustomFields)->getGlobalFields()['fields']; if (!empty($allCustomFields) && !empty($enabledCustomFieldSlugs)) { foreach ($allCustomFields as $field) { $fieldKey = $field['slug']; // Only process fields that are enabled in pref_custom if (!in_array($fieldKey, $enabledCustomFieldSlugs)) { continue; } if (isset($validData[$fieldKey])) { $value = $validData[$fieldKey]; // Handle different field types switch ($field['type']) { case 'checkbox': if (is_array($value)) { $value = array_map('sanitize_text_field', $value); } break; case 'select-multi': if (is_array($value)) { $value = array_map('sanitize_text_field', $value); } else { $value = []; } break; case 'number': $value = floatval($value); break; case 'textarea': $value = isset($_POST[$fieldKey]) ? sanitize_textarea_field($_POST[$fieldKey]) : ''; break; case 'date': $value = sanitize_text_field($value); break; default: $value = sanitize_text_field($value); } // Update the meta with proper type $subscriber->updateMeta($field['slug'], $value, 'custom_field'); unset($validData[$fieldKey]); // Remove from main data } } } $subscriber->fill($validData); $updateData = $subscriber->getDirty(); if($updateData) { $subscriber->save(); } if (isset($_REQUEST['lists'])) { $publicLists = Helper::getPublicLists(); $publicListIds = []; foreach ($publicLists as $publicList) { $publicListIds[] = $publicList->id; } $selectedListIds = map_deep($_REQUEST['lists'], 'intval'); $attachLists = []; $detachLists = []; foreach ($subscriber->lists as $list) { if (!in_array($list->id, $publicListIds)) { continue; } if (!in_array($list->id, $selectedListIds)) { $detachLists[] = $list->id; } } foreach ($selectedListIds as $selectedListId) { if (in_array($selectedListId, $publicListIds)) { $attachLists[] = $selectedListId; } } if ($attachLists) { $subscriber->attachLists($attachLists); } if ($detachLists) { $subscriber->detachLists($detachLists); } } else { $listIds = $subscriber->lists()->get()->pluck('id')->toArray(); $subscriber->detachLists($listIds); } do_action('fluent_crm/pref_form_self_contact_updated', $subscriber, $_REQUEST); if ($updateData) { do_action('fluentcrm_contact_updated', $subscriber, $updateData); do_action('fluent_crm/contact_updated', $subscriber, $updateData); } wp_send_json_success([ 'message' => __('Your information has been updated', 'fluent-crm'), 'data' => $validData ], 200); } private function getFormFields($settings, $subscriber, $labels, $inputOnly = false) { $generalFields = Arr::get($settings, 'pref_general'); $customFields = Arr::get($settings, 'pref_custom'); $formFields = []; if (array_intersect($generalFields, ['first_name', 'last_name'])) { $nameFields = []; if (in_array('prefix', $generalFields)) { $nameFields['prefix'] = [ 'type' => 'select', 'name' => 'prefix', 'container_class' => 'fc_name_prefix', 'id' => 'fc_name_prefix', 'label' => Arr::get($labels, 'prefix', 'Prefix'), 'placeholder' => '--', 'options' => Helper::getContactPrefixes(true), 'value' => $subscriber->prefix ]; } if (in_array('first_name', $generalFields)) { $nameFields['first_name'] = [ 'type' => 'input', 'name' => 'first_name', 'id' => 'fc_first_name', 'atts' => [ 'type' => 'text', 'placeholder' => __('First Name', 'fluent-crm') ], 'required' => true, 'label' => Arr::get($labels, 'first_name', 'First Name'), 'value' => $subscriber->first_name ]; } if (in_array('last_name', $generalFields)) { $nameFields['last_name'] = [ 'type' => 'input', 'name' => 'last_name', 'id' => 'fc_last_name', 'atts' => [ 'type' => 'text', 'placeholder' => __('Last Name', 'fluent-crm') ], 'required' => true, 'label' => Arr::get($labels, 'last_name', 'Last Name'), 'value' => $subscriber->last_name ]; } $formFields['name'] = [ 'type' => 'container', 'container_class' => 'fc_names fc_' . count($nameFields) . '_col', 'fields' => $nameFields ]; } $formFields[] = [ 'type' => 'raw_html', 'html' => '