: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
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 list of available providers.
add_filter( 'wpforms_providers_available', [ $this, 'register_provider' ], $this->priority, 1 );
// 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 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() {
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
if ( 'new_connection' === $task ) {
$connection = $this->output_connection(
'connection_name' => $name,
* Create new Provider account.
if ( 'new_account' === $task ) {
$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 ( 'select_account' === $task ) {
$lists = $this->output_lists(
'account_id' => $account_id,
if ( is_wp_error( $lists ) ) {
'error' => $lists->get_error_message(),
* Select/Toggle Provider account lists.
if ( 'select_list' === $task ) {
$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.
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 a
* white-list. Also some fields, such as Name, should have additional
* @param object|bool $form
* @param array $whitelist
public function get_form_fields( $form = false, $whitelist = [] ) {
// Accept form (post) object or form ID.
if ( is_object( $form ) ) {
$form = wpforms_decode( $form->post_content );
} elseif ( is_numeric( $form ) ) {
$form = wpforms()->get( 'form' )->get(
if ( ! is_array( $form ) || empty( $form['fields'] ) ) {
// White list of field types to allow.
$allowed_form_fields = apply_filters( 'wpforms_providers_fields', $allowed_form_fields );
$whitelist = ! empty( $whitelist ) ? $whitelist : $allowed_form_fields;
$form_fields = $form['fields'];
foreach ( $form_fields as $id => $form_field ) {
if ( ! in_array( $form_field['type'], $whitelist, 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
* @param array $form_fields
* @param string $form_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 ) {
'email' === $form_field_type &&
! in_array( $form_field['type'], [ 'text', 'email' ], true )
unset( $form_fields[ $id ] );
'address' === $form_field_type &&
! in_array( $form_field['type'], [ 'address' ], true )
unset( $form_fields[ $id ] );
foreach ( $form_fields as $id => $form_field ) {
if ( 'name' === $form_field['type'] ) {
'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'],
'type' => $form_field['type'],
'provider_type' => $form_field_type,
/* translators: %s - Name field label. */
esc_html__( '%s (First)', 'wpforms-lite' ),