is_safe_admin_context() ) { return $form; } if ( ! $this->is_tracking_enabled( $form ) ) { return $form; } // Idempotency guard: if the tracking fields are already present (e.g. an // external update_form() persisted them), do not inject a second copy. $existing_fields = isset( $form['fields'] ) && is_array( $form['fields'] ) ? $form['fields'] : array(); foreach ( $existing_fields as $existing ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- cssClass is Gravity Forms' own field property name. $css = is_object( $existing ) ? (string) $existing->cssClass : (string) ( $existing['cssClass'] ?? '' ); if ( false !== strpos( $css, Constants::FIELD_CSS_PREFIX ) ) { return $form; } } $constants = Constants::get_instance(); $base = $constants->get_base_gfield_id(); $prefix = Constants::FIELD_CSS_PREFIX; $definitions = array( array( 'id' => $base . $constants->get_gfield_id( 'source' ), 'label' => esc_html__( 'Ad Source', 'ad-click-tracking-for-gravity-forms' ), 'cssClass' => $prefix . 'source', ), array( 'id' => $base . $constants->get_gfield_id( 'network' ), 'label' => esc_html__( 'Ad Network', 'ad-click-tracking-for-gravity-forms' ), 'cssClass' => $prefix . 'network', ), array( 'id' => $base . $constants->get_gfield_id( 'clid' ), 'label' => esc_html__( 'Ad Click ID', 'ad-click-tracking-for-gravity-forms' ), 'cssClass' => $prefix . 'clid', ), ); foreach ( $definitions as $definition ) { if ( class_exists( '\GF_Field_Hidden' ) ) { $form['fields'][] = new \GF_Field_Hidden( $definition ); } else { $definition['visibility'] = 'hidden'; $form['fields'][] = new \GF_Field_Text( $definition ); } } return $form; } /** * Adds the per-form enable toggle to the Gravity Forms form settings. * * @param array $fields Existing settings fields. * @param array $form Current form. * @return array */ public function register_form_setting( $fields, $form ) { if ( ! isset( $fields['form_options']['fields'] ) || ! is_array( $fields['form_options']['fields'] ) ) { return $fields; } $label = esc_html__( 'Enable ad click tracking', 'ad-click-tracking-for-gravity-forms' ); $tooltip = esc_html__( 'Capture Google, Microsoft and Meta ad click IDs on this form.', 'ad-click-tracking-for-gravity-forms' ); $fields['form_options']['fields'][] = array( 'name' => Constants::ENABLE_SETTING_KEY, 'type' => 'toggle', 'label' => $label, 'default_value' => (int) get_option( Constants::DEFAULT_ENABLED_OPTION, 0 ), 'tooltip' => '', ); $fields['form_options']['fields'][] = array( 'name' => 'pb_act_upgrade_note', 'type' => 'html', 'html' => Upsell::note( 'gf-form-settings' ), ); return $fields; } /** * Fills the Source default when a submission arrives with an empty field. * * @param array $form Form data. * @return array */ public function ensure_defaults_on_submit( $form ) { $constants = Constants::get_instance(); $source_id = $constants->get_base_gfield_id() . $constants->get_gfield_id( 'source' ); $field_key = 'input_' . $source_id; // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Gravity Forms' own submission payload; the value is only compared for emptiness, never stored. if ( isset( $_POST[ $field_key ] ) && '' === trim( (string) wp_unslash( $_POST[ $field_key ] ) ) ) { $_POST[ $field_key ] = 'Unknown'; } return $form; } /** * Whether tracking is enabled for the form (per-form value or global default). * * @param array $form Form data. */ private function is_tracking_enabled( array $form ): bool { if ( isset( $form[ Constants::ENABLE_SETTING_KEY ] ) ) { return 1 === (int) $form[ Constants::ENABLE_SETTING_KEY ]; } return 1 === (int) get_option( Constants::DEFAULT_ENABLED_OPTION, 0 ); } /** * Restricts admin-side field injection to the read-only entry detail view. * * Injecting on the entry edit screen would let Gravity Forms overwrite saved * tracking data with empty values when an admin saves the entry. */ private function is_safe_admin_context(): bool { if ( class_exists( '\GFCommon' ) ) { $is_entry_detail = \GFCommon::is_entry_detail(); $is_entry_detail_edit = method_exists( '\GFCommon', 'is_entry_detail_edit' ) && \GFCommon::is_entry_detail_edit(); if ( ! $is_entry_detail || $is_entry_detail_edit ) { return false; } } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin screen detection. if ( isset( $_GET['page'] ) && 'gf_edit_forms' === sanitize_text_field( wp_unslash( $_GET['page'] ) ) ) { return false; } if ( function_exists( 'get_current_screen' ) ) { $screen = get_current_screen(); if ( $screen && in_array( $screen->base, array( 'post', 'site-editor' ), true ) ) { return false; } } return true; } }