queueService = $queueService;
$this->connectionRepository = $connectionRepository;
}
/**
* @inheritDoc
*/
public function getId(): string
{
return 'wpforms';
}
/**
* @inheritDoc
*/
public function getName(): string
{
return __('WPForms', '1-click-form-sync');
}
/**
* @inheritDoc
*/
public function isAvailable(): bool
{
return class_exists('WPForms\WPForms') || class_exists('WPForms_Lite') || function_exists('wpforms');
}
/**
* @inheritDoc
*/
public function register(): void
{
if (!$this->isAvailable()) {
return;
}
// Register custom settings tab/section inside WPForms builder Settings
add_filter('wpforms_builder_settings_sections', [$this, 'addSettingsSection'], 20, 2);
add_action('wpforms_form_settings_panel_content', [$this, 'renderSettingsPanel'], 20, 1);
add_action('admin_enqueue_scripts', [$this, 'enqueueBuilderAssets']);
// Capture submissions
add_action('wpforms_process_complete', [$this, 'processSubmission'], 10, 4);
}
/**
* Add settings section tab sidebar in WPForms builder.
*
* @param array $sections
* @param array $form_data
* @return array
*/
public function addSettingsSection(array $sections, array $form_data): array
{
$sections['oneclickformsync'] = esc_html__('1 Click Form Sync', '1-click-form-sync');
return $sections;
}
/**
* Render the settings fields inside the settings tab.
*
* @param object $builder_panel_settings
* @return void
*/
public function renderSettingsPanel($builder_panel_settings): void
{
if (!function_exists('wpforms_panel_field')) {
return;
}
$form_data = $builder_panel_settings->form_data;
$settings = $form_data['settings'] ?? [];
$connections = $this->connectionRepository->findAll();
$connectionOptions = ['' => __('Select Connection...', '1-click-form-sync')];
foreach ($connections as $conn) {
$connectionOptions[$conn->getId()] = $conn->getName() . ' (' . $conn->getEmail() . ')';
}
echo '
';
echo '
' . esc_html__('1 Click Form Sync Settings', '1-click-form-sync') . '
';
// 1. Google Connection Select
wpforms_panel_field(
'select',
'settings',
'oneclickformsync_connection_id',
$form_data,
esc_html__('Google Connection', '1-click-form-sync'),
[
'options' => $connectionOptions,
]
);
// 2. Spreadsheet ID or URL
wpforms_panel_field(
'text',
'settings',
'oneclickformsync_spreadsheet_id',
$form_data,
esc_html__('Spreadsheet URL or ID', '1-click-form-sync'),
[
'placeholder' => 'https://docs.google.com/spreadsheets/d/.../edit',
]
);
// 3. Worksheet Name
wpforms_panel_field(
'text',
'settings',
'oneclickformsync_worksheet_name',
$form_data,
esc_html__('Worksheet Name', '1-click-form-sync'),
[
'default' => 'Sheet1',
]
);
// 4. Create Headers Toggle
wpforms_panel_field(
'toggle',
'settings',
'oneclickformsync_create_headers',
$form_data,
esc_html__('Create Headers if Empty', '1-click-form-sync'),
[
'default' => '1',
]
);
// 4.1 Header Background Color
wpforms_panel_field(
'text',
'settings',
'oneclickformsync_header_bg_color',
$form_data,
esc_html__('Header Background Color', '1-click-form-sync'),
[
'default' => '#2d3748',
'placeholder' => '#2d3748',
'description' => __('Enter a hex color code (e.g. #2d3748) for the header background color.', '1-click-form-sync'),
]
);
// 4.2 Header Text Color
wpforms_panel_field(
'text',
'settings',
'oneclickformsync_header_fg_color',
$form_data,
esc_html__('Header Text Color', '1-click-form-sync'),
[
'default' => '#ffffff',
'placeholder' => '#ffffff',
'description' => __('Enter a hex color code (e.g. #ffffff) for the header text color.', '1-click-form-sync'),
]
);
// 4.3 Freeze Header Row
wpforms_panel_field(
'toggle',
'settings',
'oneclickformsync_header_sticky',
$form_data,
esc_html__('Freeze Header Row (Sticky)', '1-click-form-sync'),
[
'default' => '1',
]
);
// 5. Mapping Mode
wpforms_panel_field(
'select',
'settings',
'oneclickformsync_mapping_mode',
$form_data,
esc_html__('Mapping Mode', '1-click-form-sync'),
[
'options' => [
'auto' => __('Automatic Mapping', '1-click-form-sync'),
'custom' => __('Custom Mapping', '1-click-form-sync'),
],
'default' => 'auto',
'class' => 'oneclickformsync-mapping-mode-select',
]
);
// 6. Custom Field Mappings (Textarea)
wpforms_panel_field(
'textarea',
'settings',
'oneclickformsync_custom_mapping_text',
$form_data,
esc_html__('Custom Field Mappings', '1-click-form-sync'),
[
'placeholder' => "First Name = 1\nEmail = 2\nDate = {submission_date} | | raw",
'description' => __('Enter each mapping on a new line. Format: Sheet Column = Field ID | Default Value | Formatting (raw, uppercase, lowercase). To find field IDs, look at the fields in the WPForms builder (e.g. 1, 2, 3).', '1-click-form-sync'),
]
);
// 7. Metadata Column Switches
echo '
';
echo '
' . esc_html__('Include Metadata Columns (Auto Mode)', '1-click-form-sync') . '
';
$metaFields = [
'oneclickformsync_include_submission_id' => __('Submission ID', '1-click-form-sync'),
'oneclickformsync_include_submission_date' => __('Date', '1-click-form-sync'),
'oneclickformsync_include_submission_time' => __('Submission Time', '1-click-form-sync'),
'oneclickformsync_include_form_id' => __('Form ID', '1-click-form-sync'),
'oneclickformsync_include_form_name' => __('Form Name', '1-click-form-sync'),
'oneclickformsync_include_page_url' => __('Page URL', '1-click-form-sync'),
'oneclickformsync_include_utm_source' => __('UTM Source', '1-click-form-sync'),
'oneclickformsync_include_utm_medium' => __('UTM Medium', '1-click-form-sync'),
'oneclickformsync_include_utm_campaign' => __('UTM Campaign', '1-click-form-sync'),
'oneclickformsync_include_utm_term' => __('UTM Term', '1-click-form-sync'),
'oneclickformsync_include_utm_content' => __('UTM Content', '1-click-form-sync'),
];
foreach ($metaFields as $key => $label) {
wpforms_panel_field(
'toggle',
'settings',
$key,
$form_data,
$label
);
}
echo '';
// 8. Custom UTM / query parameters
wpforms_panel_field(
'text',
'settings',
'oneclickformsync_custom_utm_params',
$form_data,
esc_html__('Custom Tracking Parameters', '1-click-form-sync'),
[
'placeholder' => 'gclid, fbclid, msclkid',
'description' => __('Enter a comma-separated list of additional query parameters to track.', '1-click-form-sync'),
]
);
echo '
';
}
/**
* Enqueue builder scripts and styles using WordPress wp_enqueue functions.
*
* @param string $hook
* @return void
*/
public function enqueueBuilderAssets(string $hook): void
{
if (strpos($hook, 'wpforms') === false) {
return;
}
$customCss = '.oneclickformsync-meta-options-row { margin-left: 20px; border-left: 3px solid #e2e8f0; padding-left: 15px; }';
wp_register_style('oneclickformsync-wpforms-builder-style', false);
wp_enqueue_style('oneclickformsync-wpforms-builder-style');
wp_add_inline_style('oneclickformsync-wpforms-builder-style', $customCss);
$customJs = "jQuery(document).ready(function($) {
function toggleOneClickFormSyncFields() {
var mode = $('#wpforms-panel-field-settings-oneclickformsync_mapping_mode').val();
if (mode === 'custom') {
$('#wpforms-panel-field-settings-oneclickformsync_custom_mapping_text-row').show();
$('.oneclickformsync-meta-options-row').hide();
} else {
$('#wpforms-panel-field-settings-oneclickformsync_custom_mapping_text-row').hide();
$('.oneclickformsync-meta-options-row').show();
}
}
$(document).on('change', '#wpforms-panel-field-settings-oneclickformsync_mapping_mode', toggleOneClickFormSyncFields);
toggleOneClickFormSyncFields();
});";
wp_register_script('oneclickformsync-wpforms-builder-js', false, ['jquery'], '1.0.0', true);
wp_enqueue_script('oneclickformsync-wpforms-builder-js');
wp_add_inline_script('oneclickformsync-wpforms-builder-js', $customJs);
}
/**
* Process submission from WPForms.
*
* @param array $fields
* @param array $entry
* @param array $form_data
* @param int $entry_id
* @return void
*/
public function processSubmission(array $fields, array $entry, array $form_data, int $entry_id): void
{
$settings = $form_data['settings'] ?? [];
$connectionId = $settings['oneclickformsync_connection_id'] ?? '';
$spreadsheetId = $settings['oneclickformsync_spreadsheet_id'] ?? '';
$worksheetName = $settings['oneclickformsync_worksheet_name'] ?? 'Sheet1';
if (empty($connectionId) || empty($spreadsheetId) || empty($worksheetName)) {
return;
}
// Parse custom mappings textarea to custom mapping array
$customMappingText = $settings['oneclickformsync_custom_mapping_text'] ?? '';
$customMapping = [];
if (!empty($customMappingText)) {
$lines = explode("\n", str_replace("\r", "", $customMappingText));
foreach ($lines as $line) {
$line = trim($line);
if (empty($line)) {
continue;
}
$parts = explode('=', $line, 2);
if (count($parts) === 2) {
$column = trim($parts[0]);
$rest = trim($parts[1]);
$restParts = explode('|', $rest);
$fieldId = trim($restParts[0] ?? '');
$defaultValue = trim($restParts[1] ?? '');
$formatting = trim($restParts[2] ?? 'raw');
if ($column !== '') {
$customMapping[] = [
'sheet_column' => $column,
'form_field' => $fieldId,
'default_value' => $defaultValue,
'formatting' => $formatting,
];
}
}
}
}
$configSettings = [
'connection_id' => $connectionId,
'spreadsheet_id' => $spreadsheetId,
'worksheet_name' => $worksheetName,
'mapping_mode' => $settings['oneclickformsync_mapping_mode'] ?? 'auto',
'custom_mapping' => $customMapping,
'create_headers' => ($settings['oneclickformsync_create_headers'] ?? '') === '1' || ($settings['oneclickformsync_create_headers'] ?? '') === 'yes',
'include_submission_id' => ($settings['oneclickformsync_include_submission_id'] ?? '') === '1' || ($settings['oneclickformsync_include_submission_id'] ?? '') === 'yes',
'include_submission_date' => ($settings['oneclickformsync_include_submission_date'] ?? '') === '1' || ($settings['oneclickformsync_include_submission_date'] ?? '') === 'yes',
'include_submission_time' => ($settings['oneclickformsync_include_submission_time'] ?? '') === '1' || ($settings['oneclickformsync_include_submission_time'] ?? '') === 'yes',
'include_form_id' => ($settings['oneclickformsync_include_form_id'] ?? '') === '1' || ($settings['oneclickformsync_include_form_id'] ?? '') === 'yes',
'include_form_name' => ($settings['oneclickformsync_include_form_name'] ?? '') === '1' || ($settings['oneclickformsync_include_form_name'] ?? '') === 'yes',
'include_page_url' => ($settings['oneclickformsync_include_page_url'] ?? '') === '1' || ($settings['oneclickformsync_include_page_url'] ?? '') === 'yes',
'include_utm_source' => ($settings['oneclickformsync_include_utm_source'] ?? '') === '1' || ($settings['oneclickformsync_include_utm_source'] ?? '') === 'yes',
'include_utm_medium' => ($settings['oneclickformsync_include_utm_medium'] ?? '') === '1' || ($settings['oneclickformsync_include_utm_medium'] ?? '') === 'yes',
'include_utm_campaign' => ($settings['oneclickformsync_include_utm_campaign'] ?? '') === '1' || ($settings['oneclickformsync_include_utm_campaign'] ?? '') === 'yes',
'include_utm_term' => ($settings['oneclickformsync_include_utm_term'] ?? '') === '1' || ($settings['oneclickformsync_include_utm_term'] ?? '') === 'yes',
'include_utm_content' => ($settings['oneclickformsync_include_utm_content'] ?? '') === '1' || ($settings['oneclickformsync_include_utm_content'] ?? '') === 'yes',
'custom_utm_params' => $settings['oneclickformsync_custom_utm_params'] ?? '',
'header_bg_color' => $settings['oneclickformsync_header_bg_color'] ?? '',
'header_fg_color' => $settings['oneclickformsync_header_fg_color'] ?? '',
'header_sticky' => ($settings['oneclickformsync_header_sticky'] ?? '') === '1' || ($settings['oneclickformsync_header_sticky'] ?? '') === 'yes',
];
$rawData = [
'fields' => $fields,
'form_data' => $form_data,
];
$submission = $this->normalizeSubmission($rawData, $configSettings);
$submission = apply_filters('oneclickformsync_normalized_submission', $submission, $configSettings);
$this->queueService->enqueue($submission, $configSettings);
}
/**
* @inheritDoc
*/
public function normalizeSubmission($submission, array $settings): NormalizedSubmission
{
$normalizer = new WPFormsSubmissionNormalizer();
$customParams = $settings['custom_utm_params'] ?? '';
return $normalizer->normalize($submission, $customParams);
}
}