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); } }