// phpcs:disable Generic.Commenting.DocComment.MissingShort
/** @noinspection PhpIllegalPsrClassPathInspection */
/** @noinspection AutoloadingIssuesInspection */
// phpcs:enable Generic.Commenting.DocComment.MissingShort
use WPForms\Providers\Provider\Settings\FormBuilder;
use WPForms\Providers\Provider\Status;
abstract class WPForms_Provider {
* Provider addon version.
* Provider name in slug format.
* Store the API connections.
* Form data and settings.
* Primary class constructor.
public function __construct() {
$this->type = esc_html__( 'Connection', 'wpforms-lite' );
private function hooks() {
// Add to a list of available providers.
add_filter( 'wpforms_providers_available', [ $this, 'register_provider' ], $this->priority );
// Process builder AJAX requests.
add_action( "wp_ajax_wpforms_provider_ajax_$this->slug", [ $this, 'process_ajax' ] );
add_action( 'wpforms_process_complete', [ $this, 'process_entry' ], 5, 4 );
// Fetch and store the current form data when in the builder.
add_action( 'wpforms_builder_init', [ $this, 'builder_form_data' ] );
// Output builder sidebar.
add_action( 'wpforms_providers_panel_sidebar', [ $this, 'builder_sidebar' ], $this->priority );
// Output builder content.
add_action( 'wpforms_providers_panel_content', [ $this, 'builder_output' ], $this->priority );
// Remove provider from Settings Integrations tab.
add_action( "wp_ajax_wpforms_settings_provider_disconnect_$this->slug", [ $this, 'integrations_tab_disconnect' ] );
// Add new provider from Settings Integrations tab.
add_action( "wp_ajax_wpforms_settings_provider_add_$this->slug", [ $this, 'integrations_tab_add' ] );
// Add providers sections to the Settings Integrations tab.
add_action( 'wpforms_settings_providers', [ $this, 'integrations_tab_options' ], $this->priority, 2 );
* Add to a list of registered providers.
* @param array $providers Array of all active providers.
public function register_provider( $providers = [] ) {
$providers[ $this->slug ] = $this->name;
* Process the Builder AJAX requests.
public function process_ajax() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
check_ajax_referer( 'wpforms-builder', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can( 'edit_forms' ) ) {
'error' => esc_html__( 'You do not have permission', 'wpforms-lite' ),
$name = ! empty( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '';
$task = ! empty( $_POST['task'] ) ? sanitize_text_field( wp_unslash( $_POST['task'] ) ) : '';
$id = ! empty( $_POST['id'] ) ? sanitize_text_field( wp_unslash( $_POST['id'] ) ) : '';
$connection_id = ! empty( $_POST['connection_id'] ) ? sanitize_text_field( wp_unslash( $_POST['connection_id'] ) ) : '';
$account_id = ! empty( $_POST['account_id'] ) ? sanitize_text_field( wp_unslash( $_POST['account_id'] ) ) : '';
$list_id = ! empty( $_POST['list_id'] ) ? sanitize_text_field( wp_unslash( $_POST['list_id'] ) ) : '';
$data = ! empty( $_POST['data'] ) ? array_map( 'sanitize_text_field', wp_parse_args( wp_unslash( $_POST['data'] ) ) ) : []; //phpcs:ignore
* Create a new connection.
if ( $task === 'new_connection' ) {
$connection = $this->output_connection(
'connection_name' => $name,
* Create a new Provider account.
if ( $task === 'new_account' ) {
$auth = $this->api_auth( $data, $id );
if ( is_wp_error( $auth ) ) {
'error' => $auth->get_error_message(),
$accounts = $this->output_accounts(
* Select/Toggle Provider accounts.
if ( $task === 'select_account' ) {
$lists = $this->output_lists(
'account_id' => $account_id,
if ( is_wp_error( $lists ) ) {
'error' => $lists->get_error_message(),
* Select/Toggle Provider account lists.
if ( $task === 'select_list' ) {
$fields = $this->output_fields(
'account_id' => $account_id,
if ( is_wp_error( $fields ) ) {
'error' => $fields->get_error_message(),
$groups = $this->output_groups(
'account_id' => $account_id,
$conditionals = $this->output_conditionals(
'account_id' => $account_id,
'id' => absint( $_POST['form_id'] ), //phpcs:ignore
$options = $this->output_options(
'account_id' => $account_id,
'html' => $groups . $fields . $conditionals . $options,
* Process and submit entry to provider.
* @param array $fields List of fields in a form.
* @param array $entry Submitted entry values.
* @param array $form_data Form data and settings.
* @param int $entry_id Saved entry ID.
public function process_entry( $fields, $entry, $form_data, $entry_id ) {}
* Process conditional fields.
* @param array $fields List of fields with their data and settings.
* @param array $entry Submitted entry values.
* @param array $form_data Form data and settings.
* @param array $connection List of connection settings.
* @noinspection PhpMissingParamTypeInspection
* @noinspection PhpUnusedParameterInspection
public function process_conditionals( $fields, $entry, $form_data, $connection ) {
empty( $connection['conditional_logic'] ) ||
empty( $connection['conditionals'] ) ||
! function_exists( 'wpforms_conditional_logic' )
$process = wpforms_conditional_logic()->process( $fields, $form_data, $connection['conditionals'] );
if ( ! empty( $connection['conditional_type'] ) && $connection['conditional_type'] === 'stop' ) {
* Retrieve all available forms in a field.
* Not all fields should be available for merge tags, so we compare against an allowlist.
* Also, some fields, such as Name, should have additional variations.
* @param object|int $form Form object or form ID.
* @param array $allowlist Allowlist of field types to allow.
public function get_form_fields( $form = false, $allowlist = [] ) {
// Accept form (post) object or form ID.
if ( is_object( $form ) ) {
$form = wpforms_decode( $form->post_content );
} elseif ( is_numeric( $form ) ) {
$form_obj = wpforms()->obj( 'form' );
? $form_obj->get( $form, [ 'content_only' => true ] )
if ( ! is_array( $form ) || empty( $form['fields'] ) ) {
// Allowlist of field types to allow.
* Filter the allowed form fields for the provider.
* @param array $allowed_form_fields List of allowed form fields.
$allowed_form_fields = (array) apply_filters( 'wpforms_providers_fields', $allowed_form_fields );
$allowlist = ! empty( $allowlist ) ? $allowlist : $allowed_form_fields;
$form_fields = $form['fields'];
foreach ( $form_fields as $id => $form_field ) {
if ( ! in_array( $form_field['type'], $allowlist, true ) ) {
unset( $form_fields[ $id ] );
* Get form fields ready for select list options.
* In this function, we also do the logic to limit certain fields to certain provider field types.
* @param array $form_fields List of form fields.
* @param string $form_field_type Provider field type.
public function get_form_field_select( $form_fields = [], $form_field_type = '' ) {
if ( empty( $form_fields ) || empty( $form_field_type ) ) {
// Include only specific field types.
foreach ( $form_fields as $id => $form_field ) {
$form_field_type === 'email' &&
! in_array( $form_field['type'], [ 'text', 'email' ], true )
unset( $form_fields[ $id ] );
if ( $form_field_type === 'address' && $form_field['type'] !== 'address' ) {
unset( $form_fields[ $id ] );
foreach ( $form_fields as $form_field ) {
if ( $form_field['type'] === 'name' ) {
'id' => $form_field['id'],
'type' => $form_field['type'],
'provider_type' => $form_field_type,
/* translators: %s - Name field label. */
esc_html__( '%s (Full)', 'wpforms-lite' ),
if ( strpos( $form_field['format'], 'first' ) !== false ) {
'id' => $form_field['id'],