HEX
Server: Apache/2.4.68 (Debian)
System: Linux as-cs-widget-demo-us-central1 6.1.0-44-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.164-1 (2026-03-09) x86_64
User: root (0)
PHP: 8.2.32
Disabled: NONE
Upload Files
File: /var/www/kevin-demo/wp-content/plugins/wpforms-sendinblue/assets/js/sendinblue-builder.js
/* global WPForms, wpforms_builder, wpforms_builder_providers, wpf, wpformsSendinblueBuilderVars */
'use strict';

/**
 * WPForms Providers Builder Sendinblue module.
 *
 * @since 1.0.0
 */
WPForms.Admin.Builder.Providers.Sendinblue = WPForms.Admin.Builder.Providers.Sendinblue || ( function( document, window, $ ) {

	/**
	 * Private functions and properties.
	 *
	 * @since 1.0.0
	 *
	 * @type {object}
	 */
	var __private = {

		/**
		 * jQuery object for holder.
		 *
		 * @since 1.0.0
		 *
		 * @type {jQuery}
		 */
		$holder: null,

		/**
		 * Config contains all configuration properties.
		 *
		 * @since 1.0.0
		 *
		 * @type {object}
		 */
		config: {

			/**
			 * List of Sendinblue templates that should be compiled.
			 *
			 * @since 1.0.0
			 *
			 * @type {Array}
			 */
			templates: [
				'wpforms-sendinblue-builder-content-connection',
				'wpforms-sendinblue-builder-content-connection-required-email-select-field',
				'wpforms-sendinblue-builder-content-connection-required-select-field',
				'wpforms-sendinblue-builder-content-connection-required-text-field',
				'wpforms-sendinblue-builder-content-connection-required-toggle-field',
				'wpforms-sendinblue-builder-content-connection-required-url-field',
				'wpforms-sendinblue-builder-content-connection-error',
				'wpforms-sendinblue-builder-content-connection-conditionals',
			],
		},

		/**
		 * Sometimes in DOM we might have placeholders or temporary connection IDs.
		 * We need to replace them with actual values.
		 *
		 * @since 1.0.0
		 *
		 * @param {string} connectionId New connection ID to replace to.
		 * @param {object} $connection  jQuery DOM connection element.
		 */
		replaceConnectionIds: function( connectionId, $connection ) {

			// Replace old temporary %connection_id% from PHP code with the new one.
			$connection.find( 'input, textarea, select, label' ).each( function() {

				var $this = $( this );

				if ( $this.attr( 'name' ) ) {
					$this.attr( 'name', $this.attr( 'name' ).replace( /%connection_id%/gi, connectionId ) );
				}

				if ( $this.attr( 'id' ) ) {
					$this.attr( 'id', $this.attr( 'id' ).replace( /%connection_id%/gi, connectionId ) );
				}

				if ( $this.attr( 'for' ) ) {
					$this.attr( 'for', $this.attr( 'for' ).replace( /%connection_id%/gi, connectionId ) );
				}

				if ( $this.attr( 'data-name' ) ) {
					$this.attr( 'data-name', $this.attr( 'data-name' ).replace( /%connection_id%/gi, connectionId ) );
				}
			} );
		},

		/**
		 * Whether we have an account ID in a list of all available accounts.
		 *
		 * @since 1.0.0
		 *
		 * @param {string} connectionAccID Connection account ID to check.
		 * @param {object}  accounts        Array of objects, usually received from API.
		 *
		 * @returns {boolean} True if connection already exists.
		 */
		connectionAccountExists: function( connectionAccID, accounts ) {

			if ( _.isEmpty( accounts ) ) {
				return false;
			}

			// New connections, that have not been saved don't have the account ID yet.
			if ( _.isEmpty( connectionAccID ) ) {
				return true;
			}

			return _.has( accounts, connectionAccID );
		},
	};

	// noinspection JSUnusedLocalSymbols,JSUnusedGlobalSymbols
	/**
	 * Public functions and properties.
	 *
	 * @since 1.0.0
	 *
	 * @type {object}
	 */
	var app = {

		/**
		 * Current provider slug.
		 *
		 * @since 1.0.0
		 *
		 * @type {string}
		 */
		provider: 'sendinblue',

		/**
		 * This is a shortcut to the WPForms.Admin.Builder.Providers object,
		 * that handles the parent all-providers functionality.
		 *
		 * @since 1.0.0
		 *
		 * @type {object}
		 */
		Providers: {},

		/**
		 * This is a shortcut to the WPForms.Admin.Builder.Templates object,
		 * that handles all the template management.
		 *
		 * @since 1.0.0
		 *
		 * @type {object}
		 */
		Templates: {},

		/**
		 * This is a shortcut to the WPForms.Admin.Builder.Providers.cache object,
		 * that handles all the cache management.
		 *
		 * @since 1.0.0
		 *
		 * @type {object}
		 */
		Cache: {},

		/**
		 * This is a flag for ready state.
		 *
		 * @since 1.0.0
		 *
		 * @type {boolean}
		 */
		isReady: false,

		/**
		 * Start the engine.
		 *
		 * Run initialization on providers panel only.
		 *
		 * @since 1.0.0
		 */
		init: function() {

			// We are requesting/loading a Providers panel.
			if ( 'providers' === wpf.getQueryString( 'view' ) ) {
				$( '#wpforms-panel-providers' ).on( 'WPForms.Admin.Builder.Providers.ready', app.ready );
			}

			// We have switched to Providers panel.
			$( document ).on( 'wpformsPanelSwitched', function( e, panel ) {

				if ( 'providers' === panel ) {
					app.ready();
				}
			} );
		},

		/**
		 * Initialized once the DOM and Providers are fully loaded.
		 *
		 * @since 1.0.0
		 */
		ready: function() {

			if ( app.isReady ) {
				return;
			}

			// Done by reference, so we are not doubling memory usage.
			app.Providers = WPForms.Admin.Builder.Providers;
			app.Templates = WPForms.Admin.Builder.Templates;
			app.Cache     = app.Providers.cache;

			// Save a jQuery object for the provider holder.
			__private.$holder = app.Providers.getProviderHolder( app.provider ).find( '.wpforms-builder-provider-connections' );

			// Register custom Underscore.js templates.
			app.Templates.add( __private.config.templates );

			// Register a handler for the "Add New Account" process.
			app.Providers.ui.account.registerAddHandler( app.provider, app.processAccountAdd );

			// Events registration.
			app.bindUIActions();
			app.bindTriggers();

			app.processInitial();

			// Save a flag for ready state.
			app.isReady = true;
		},

		/**
		 * Process various events as a response to UI interactions.
		 *
		 * @since 1.0.0
		 */
		bindUIActions: function() {

			app
				.Providers.getProviderHolder( app.provider )
				.on( 'connectionCreate', app.connection.callbacks.create )
				.on( 'connectionDelete', app.connection.callbacks.delete )
				.on( 'change', '.js-wpforms-builder-sendinblue-provider-connection-account', app.ui.account.changeCallback )
				.on( 'change', '.js-wpforms-builder-sendinblue-provider-connection-action', app.ui.action.changeCallback )
				.on( 'change', '.wpforms-builder-sendinblue-provider-opt_in', app.ui.action.changeOptInCallback );
		},

		/**
		 * Fire certain events on certain actions, specific for related connections.
		 * These are not directly caused by user manipulations.
		 *
		 * @since 1.0.0
		 */
		bindTriggers: function() {

			// Connection data was loaded.
			__private.$holder.on( 'connectionsDataLoaded', function( e, data ) {

				if ( _.isEmpty( data.connections ) ) {
					return;
				}

				for ( var connectionId in data.connections ) {
					app.connection.callbacks.generate( {
						connection: data.connections[ connectionId ],
						conditional: data.conditionals[ connectionId ],
					} );
				}
			} );

			// Connection was generated.
			__private.$holder.on( 'connectionGenerated', function( e, data ) {

				var $connection = app.connection.getById( data.connection.id );

				if ( _.has( data.connection, 'isNew' ) && data.connection.isNew ) {

					// Run replacing temporary connection ID, if it a new connection.
					__private.replaceConnectionIds( data.connection.id, $connection );
					return;
				}

				$( '.js-wpforms-builder-sendinblue-provider-connection-action', $connection ).trigger( 'change', [ $connection ] );
			} );

			// Connection was rendered.
			__private.$holder.on( 'connectionRendered', function() {

				$( '.wpforms-builder-sendinblue-provider-opt_in', ).trigger( 'change' );
			} );
		},

		/**
		 * Compile template with data if any and display them on a page.
		 *
		 * @since 1.0.0
		 */
		processInitial: function() {

			__private.$holder.prepend( app.tmpl.callbacks.commonsHTML() );
			app.connection.callbacks.dataLoad();
		},

		/**
		 * Process the account creation in FormBuilder.
		 *
		 * @since 1.0.0
		 *
		 * @param {object} modal jQuery-Confirm modal object.
		 *
		 * @returns {boolean} False.
		 */
		processAccountAdd: function( modal ) {

			var $confirmBtn  = modal.$$add;

			if ( $confirmBtn.prop( 'disabled' ) ) {
				return false;
			}

			var $error       = modal.$content.find( '.form-error' ),
				$apiKeyField = modal.$content.find( 'input[name="api_key"]' ),
				$apiKeyError = $apiKeyField.siblings( '.error' ),
				apiKey       = $apiKeyField.val().trim(),
				accountName  = modal.$content.find( 'input[name="account_name"]' ).val().trim();

			$confirmBtn.prop( 'disabled', 'disabled' );

			// Checking a required data.
			if ( _.isEmpty( apiKey ) ) {
				$apiKeyField.addClass( 'wpforms-error' );
				$confirmBtn.removeProp( 'disabled' ).removeAttr( 'disabled' );

				$apiKeyError.text( wpforms_builder_providers.required_field ).show();

				return false;
			}

			// Required data exists and not empty.
			modal.$content.find( '.wpforms-error' ).removeClass( 'wpforms-error' );
			$apiKeyError.hide();
			$error.hide();
			modal.setType( 'blue' );

			app
				.Providers.ajax
				.request( app.provider, {
					data: {
						'task': 'account_save',
						data: {
							'api_key': apiKey,
							'account_name': accountName,
						},
					},
				} )
				.done( function( response ) {

					if ( response.success ) {
						app.Providers.getProviderHolder( app.provider )
							.find( '.wpforms-builder-provider-title-add' )
							.toggleClass( 'hidden' );
						modal.close();

						return;
					}

					if ( _.has( response, 'data' ) && _.has( response.data, 'error_msg' ) ) {
						$error.html( response.data.error_msg );
					}

					$error.show();
					$confirmBtn.removeProp( 'disabled' ).removeAttr( 'disabled' );
				} );

			return false;
		},

		/**
		 * Connection property.
		 *
		 * @since 1.0.0
		 */
		connection: {

			/**
			 * Sometimes we might need to a get a connection DOM element by its ID.
			 *
			 * @since 1.0.0
			 *
			 * @param {string} connectionId Connection ID to search for a DOM element by.
			 *
			 * @returns {jQuery} jQuery object for connection.
			 */
			getById: function( connectionId ) {

				return __private.$holder.find( '.wpforms-builder-provider-connection[data-connection_id="' + connectionId + '"]' );
			},

			/**
			 * Connection methods.
			 *
			 * @since 1.0.0
			 */
			callbacks: {

				/**
				 * Create a connection using the user entered name.
				 *
				 * @since 1.0.0
				 *
				 * @param {object} event Event object.
				 * @param {string} name  Connection name.
				 */
				create: function( event, name ) {

					var connectionId = new Date().getTime().toString( 16 ),
						connection   = {
							id: connectionId,
							name: name,
							isNew: true,
						};

					app.Cache.addTo( app.provider, 'connections', connectionId, connection );

					app.connection.callbacks.generate( {
						connection: connection,
					} );
				},

				/**
				 * Connection is deleted - delete a cache as well.
				 *
				 * @since 1.0.0
				 *
				 * @param {object} event       Event object.
				 * @param {object} $connection jQuery DOM element for a connection.
				 */
				delete: function( event, $connection ) {

					var $eHolder = app.Providers.getProviderHolder( app.provider );

					if ( ! $connection.closest( $eHolder ).length ) {
						return;
					}

					var connectionId = $connection.data( 'connection_id' );

					if ( _.isString( connectionId ) ) {
						app.Cache.deleteFrom( app.provider, 'connections', connectionId );
					}
				},

				/**
				 * Get the template and data for a connection and process it.
				 *
				 * @since 1.0.0
				 *
				 * @param {object} data Connection data.
				 */
				generate: function( data ) {

					var accounts = app.Cache.get( app.provider, 'accounts' ),
						actions  = app.Cache.get( app.provider, 'actions' );

					/*
					 * We may or may not receive accounts previously.
					 * If yes - render instantly, if no - request them via AJAX.
					 */
					if ( ! _.isEmpty( accounts ) && __private.connectionAccountExists( data.connection.account_id, accounts ) ) {

						app.connection.callbacks.renderConnections( accounts, actions, data );
					} else {

						// We need to get the live list of accounts, as nothing is in cache.
						app
							.Providers.ajax
							.request( app.provider, {
								data: {
									task: 'accounts_get',
								},
							} )
							.done( function( response ) {

								if (
									! response.success ||
									! _.has( response.data, 'accounts' ) ||
									! _.has( response.data, 'actions' )
								) {
									return;
								}

								// Save ACCOUNTS in "cache" as a copy.
								app.Cache.set( app.provider, 'accounts', response.data.accounts );
								app.Cache.set( app.provider, 'actions', response.data.actions );

								app.connection.callbacks.renderConnections( response.data.accounts, response.data.actions, data );
							} );
					}
				},

				/**
				 * Render connections.
				 *
				 * @since 1.0.0
				 *
				 * @param {Object} accounts List of accounts.
				 * @param {Object} actions  List of actions.
				 * @param {Object} data     Connection data.
				 */
				renderConnections( accounts, actions, data ) {
					if ( ! __private.connectionAccountExists( data.connection.account_id, accounts ) ) {
						return;
					}

					const tmplConnection = app.Templates.get( `wpforms-${ app.provider }-builder-content-connection` ),
						tmplConditional = app.Templates.get( `wpforms-${ app.provider }-builder-content-connection-conditionals` ),
						conditional = _.has( data.connection, 'isNew' ) && data.connection.isNew ? tmplConditional() : data.conditional;

					__private
						.$holder
						.prepend(
							tmplConnection( {
								accounts: accounts,
								actions: actions,
								connection: data.connection,
								conditional: conditional,
								provider: app.provider,
							} ) );

					// When we are done adding a new connection with its accounts - trigger next steps.
					__private.$holder.trigger( 'connectionGenerated', [ data ] );
				},

				/**
				 * Fire AJAX-request to retrieve the list of all saved connections.
				 *
				 * @since 1.0.0
				 */
				dataLoad: function() {

					app
						.Providers.ajax
						.request( app.provider, {
							data: {
								task: 'connections_get',
							},
						} )
						.done( function( response ) {

							if (
								! response.success ||
								! _.has( response.data, 'connections' )
							) {
								return;
							}

							// Save response data to "cache" as a copy.
							app.Cache.set( app.provider, 'connections', jQuery.extend( {}, response.data.connections ) );
							app.Cache.set( app.provider, 'conditionals', jQuery.extend( {}, response.data.conditionals ) );
							app.Cache.set( app.provider, 'actions', jQuery.extend( {}, response.data.actions ) );

							if ( ! _.isEmpty( response.data.accounts ) ) {
								app.Cache.set( app.provider, 'accounts', jQuery.extend( {}, response.data.accounts ) );
							}

							__private.$holder.trigger( 'connectionsDataLoaded', [ response.data ] );
						} );
				},
			},
		},

		/**
		 * All methods that modify UI of a page.
		 *
		 * @since 1.0.0
		 */
		ui: {

			/**
			 * Account methods.
			 *
			 * @since 1.0.0
			 */
			account: {

				/**
				 * Callback-function on change event.
				 *
				 * @since 1.0.0
				 */
				changeCallback: function() {

					var $this       = $( this ),
						$connection = $this.closest( '.wpforms-builder-provider-connection' ),
						$actionName = $( '.js-wpforms-builder-sendinblue-provider-connection-action', $connection );

					// Clear all connection data if account was changed.
					$( '.wpforms-builder-sendinblue-provider-actions-data', $connection ).empty();
					$actionName.prop( 'selectedIndex', 0 );

					// If account is empty.
					if ( _.isEmpty( $this.val() ) ) {

						// Block `Action` select box.
						$actionName.prop( 'disabled', true );
					} else {

						// Unblock `Action` select box.
						$actionName.prop( 'disabled', false );
						$this.removeClass( 'wpforms-error' );
					}
				},
			},

			/**
			 * Action methods.
			 *
			 * @since 1.0.0
			 */
			action: {

				/**
				 * Callback-function on change event.
				 *
				 * @since 1.0.0
				 */
				changeCallback: function() {

					var $this       = $( this ),
						$connection = $this.closest( '.wpforms-builder-provider-connection' ),
						$account    = $( '.js-wpforms-builder-sendinblue-provider-connection-account', $connection ),
						$action     = $( '.js-wpforms-builder-sendinblue-provider-connection-action', $connection );

					$( '.wpforms-builder-sendinblue-provider-actions-data', $connection ).empty();
					$this.removeClass( 'wpforms-error' );

					if ( _.isEmpty( $account.val() ) || _.isEmpty( $action.val() ) ) {
						return;
					}

					app.actions.init( {
						'action': 'action',
						'target': $this,
						'account_id': $account.val(),
						'action_name': $action.val(),
						'connection_id': $connection.data( 'connection_id' ),
					} );
				},

				/**
				 * Callback-function on change opt-in field event.
				 *
				 * @since 1.1.0
				 */
				changeOptInCallback: function() {

					var $this = $( this ),
						$enableFields = $this.parent().find( '.wpforms-builder-sendinblue-provider-template_id, .wpforms-builder-sendinblue-provider-redirect_url' ),
						$disableFields = $this.parent().find( '.wpforms-builder-sendinblue-provider-new_email' );

					if ( $this.find( '.wpforms-builder-provider-connection-field-value' ).prop( 'checked' ) ) {
						$enableFields.find( '.wpforms-builder-provider-connection-field-value' ).addClass( 'wpforms-required' );
						$enableFields.removeClass( 'wpforms-hidden' );
						$disableFields.addClass( 'wpforms-hidden' );
					} else {
						$enableFields.find( '.wpforms-builder-provider-connection-field-value' ).removeClass( 'wpforms-required' );
						$enableFields.addClass( 'wpforms-hidden' );
						$disableFields.removeClass( 'wpforms-hidden' );
					}
				},
			},
		},

		/**
		 * Actions property.
		 *
		 * @since 1.0.0
		 */
		actions: {

			/**
			 * Actions initialization.
			 *
			 * @since 1.0.0
			 *
			 * @param {object} args Arguments.
			 */
			init: function( args ) {

				if ( 'action' === args.action ) {
					app.actions.action.create.init( args );
				}
			},

			/**
			 * Object actions.
			 *
			 * @since 1.0.0
			 */
			action: {

				/**
				 * Create action.
				 *
				 * @since 1.0.0
				 */
				create: {

					/**
					 * Create object initialization.
					 *
					 * @since 1.0.0
					 *
					 * @param {object} args Arguments.
					 */
					init: function( args ) {

						var self = this,
							customFields = app.Cache.get( app.provider, 'customFields' );

						if (
							! _.isObject( customFields ) ||
							_.isEmpty( customFields ) ||
							! _.has( customFields, args.account_id ) ||
							! _.has( customFields[ args.account_id ], args.target.val() )
						) {

							self.request( args );
						} else {

							self.render( args );
						}
					},

					/**
					 * AJAX request.
					 *
					 * @since 1.0.0
					 *
					 * @param {object} args Arguments.
					 */
					request: function( args ) {

						var self = this;

						// Make ajax request to get object data (fields).
						app
							.Providers.ajax
							.request( app.provider, {
								data: {
									'task': 'action_data_get',
									'account_id': args.account_id,
								},
							} )
							.done( function( response ) {

								if (
									! response.success ||
									_.isEmpty( response.data )
								) {
									__private.$holder.find( '.wpforms-builder-provider-connections-error' ).show();
									return;
								}

								// Cache response data.
								var customFields = app.Cache.get( app.provider, 'customFields' );

								if ( _.isUndefined( customFields ) ) {
									customFields = {};
									app.Cache.set( app.provider, 'customFields', customFields );
								}

								if ( ! _.has( customFields, args.account_id ) ) {
									customFields[ args.account_id ] = {};
									app.Cache.set( app.provider, 'customFields', customFields );
								}

								app.Cache.addTo( app.provider, 'customFields', args.account_id, response.data );

								// Render template.
								self.render( args );
							} );
					},

					/**
					 * Render HTML.
					 *
					 * @since 1.0.0
					 *
					 * @param {Object} args Arguments.
					 */
					render( args ) {
						const fields = wpf.getFields(),
							optionalFields = app.tmpl.callbacks.optionalFieldsHTML( args, fields ),
							requiredFields = app.tmpl.callbacks.requiredFieldsHTML( args, fields ),
							$connection = app.connection.getById( args.connection_id );

						$connection
							.find( '.wpforms-builder-sendinblue-provider-actions-data' )
							.html( requiredFields );

						// Display compiled template with custom data.
						if ( 'subscribe' === args.action_name || 'track_event' === args.action_name ) {
							$connection
								.find( '.wpforms-builder-sendinblue-provider-actions-data' )
								.append( optionalFields );
						}

						__private.$holder.trigger( 'connectionRendered', [ app.provider,
							args.connection_id ] );
					},
				},
			},
		},

		/**
		 * All methods for JavaScript templates.
		 *
		 * @since 1.0.0
		 */
		tmpl: {

			/**
			 * Wrap functions for compile JavaScript templates and receive their HTML.
			 *
			 * @since 1.0.0
			 */
			callbacks: {

				/**
				 * Compile and retrieve a HTML for common elements.
				 *
				 * @since 1.0.0
				 *
				 * @todo Since WPForms v1.9.5, this method will be redundant and can be deprecated once addon requirements are updated.
				 *
				 * @return {string} Compiled HTML.
				 */
				commonsHTML() {
					const tmplError = app.Templates.get( 'wpforms-' + app.provider + '-builder-content-connection-error' );

					return tmplError();
				},

				/**
				 * Compile and retrieve a HTML for "Custom Fields Table".
				 *
				 * @since 1.0.0
				 *
				 * @param {Object} args   Arguments
				 * @param {Object} fields Fields
				 *
				 * @return {string} Compiled HTML.
				 */
				optionalFieldsHTML( args, fields ) {
					const actionName = args.target.val(),
						tmplFields = app.Templates.get( 'wpforms-providers-builder-content-connection-fields' ),
						customFields = app.Cache.getById( app.provider, 'customFields', args.account_id ),
						connectionCache = app.Cache.getById( app.provider, 'connections', args.connection_id );
					let connectionData;

					if ( connectionCache.action !== actionName ) {
						connectionData = _.clone( connectionCache );
						// eslint-disable-next-line camelcase
						connectionData.fields_meta = [];
						// eslint-disable-next-line camelcase
						connectionData.fields_required = [];
					} else {
						connectionData = connectionCache;
					}

					return tmplFields( {
						connection: connectionData,
						fields,
						isSupportSubfields: true,
						provider: {
							placeholder: wpformsSendinblueBuilderVars.l10n.provider_placeholder,
							slug: app.provider,
							fields: customFields[ actionName ].optional,
						},
					} );
				},

				/**
				 * Compile and retrieve a HTML for "Custom Fields Table".
				 *
				 * @since 1.0.0
				 *
				 * @param {object} args Arguments
				 * @param {object} fields Fields
				 *
				 * @returns {string} Compiled HTML.
				 */
				requiredFieldsHTML: function( args, fields ) {

					var customFields = app.Cache.getById( app.provider, 'customFields', args.account_id ),
						fieldHTML = '';

					if ( ! _.has( customFields[ args.target.val() ], 'required' ) ) {
						return '';
					}

					$.each( customFields[ args.target.val() ].required, function( key, value ) {

						var tmplField = app.Templates.get( 'wpforms-' + app.provider + '-builder-content-connection-required-' + value.type.replace( '_', '-' ) + '-field' );

						fieldHTML += tmplField( {
							'connection': app.Cache.getById( app.provider, 'connections', args.connection_id ),
							'name': key,
							'field': value,
							'provider': {
								'slug': app.provider,
								'fields': customFields[ args.target.val() ].required,
							},
							'formFields': fields,
						} );
					} );

					return fieldHTML;
				},
			},
		},

		/**
		 * Modal.
		 *
		 * @since 1.0.0
		 *
		 * @param {object} data Modal data (type and message).
		 */
		modal: function( data ) {

			// Checking required data.
			if ( ! _.has( data, 'type' ) || ! _.has( data, 'message' ) ) {
				return;
			}

			var title = wpforms_builder.heads_up,
				icon = 'fa fa-exclamation-circle',
				color = 'orange';

			// Change modal attributes for success type.
			if ( data.type === 'success' ) {
				title = wpforms_builder.saved;
				icon = 'fa fa-check-circle';
				color = 'green';
			}

			$.alert( {
				title: title,
				content: data.message,
				icon: icon,
				type: color,
				buttons: {
					confirm: {
						text: wpforms_builder.ok,
						btnClass: 'btn-confirm',
						keys: [ 'enter' ],
					},
				},
			} );
		},

		/**
		 * Register a `WPForms.Admin.Builder.Providers.updatedMapSelects` core trigger when Name Format option was changed.
		 *
		 * @since 1.2.0
		 * @deprecated 1.5.0
		 *
		 * @param {Object} e Event object.
		 */
		registerTriggerOnNameFormatChange( e ) { // eslint-disable-line no-unused-vars
			// eslint-disable-next-line no-console
			console.warn( 'WARNING! Function "WPForms.Admin.Builder.Providers.Sendinblue.registerTriggerOnNameFormatChange( e )" has been deprecated.' );

			if ( __private.$holder.length ) {
				app.Providers.panelHolder.trigger( 'WPForms.Admin.Builder.Providers.updatedMapSelects', [ __private.$holder, wpf.getFields(), true ] );
			}
		},

		/**
		 * Additional preparations for the mapped selects.
		 *
		 * @since 1.2.0
		 * @deprecated 1.5.0
		 *
		 * @param {Object} e            Event object.
		 * @param {jQuery} $connections All connections.
		 * @param {Object} fields       Form fields.
		 */
		updatedMapSelectsHandler( e, $connections, fields ) {
			// eslint-disable-next-line no-console
			console.warn( 'WARNING! Function "WPForms.Admin.Builder.Providers.Sendinblue.updatedMapSelectsHandler( e, $connections, fields )" has been deprecated.' );

			const $providerConnection = $connections.filter( '.wpforms-builder-sendinblue-provider-connection' );

			if ( _.isEmpty( $providerConnection ) ) {
				return;
			}

			app.helpers.updateMapSelects( $providerConnection, fields );
		},

		/**
		 * Helper functions.
		 *
		 * @since 1.2.0
		 */
		helpers: {

			/**
			 * Prepare and retrieve fields for mapping.
			 *
			 * @since 1.2.0
			 * @deprecated 1.5.0
			 *
			 * @param {Object} fields Form fields.
			 *
			 * @return {Object} Form fields.
			 */
			getFieldsForMapping( fields ) {
				// eslint-disable-next-line no-console
				console.warn( 'WARNING! Function "WPForms.Admin.Builder.Providers.Sendinblue.getFieldsForMapping( fields )" has been deprecated.' );

				_.each( fields, function( field, key ) {
					if ( _.isEmpty( field ) || ! _.has( field, 'id' ) ) {
						return;
					}

					field.id = field.id.toString();

					if ( ! app.helpers.isNameField( field ) ) {
						return;
					}

					var fieldLabel = app.helpers.getFieldLabel( field ),
						newId;

					// Remove data for a Name field.
					delete fields[ key ];

					// Add data for Name field in "extended" format (Full, First, Middle and Last).
					_.each( wpformsSendinblueBuilderVars.l10n.nameFieldFormats, function( valueLabel, valueSlug ) {

						if (
							( _.has( field, 'format' ) && ( -1 !== field.format.indexOf( valueSlug ) ) ) ||
							( 'full' === valueSlug )
						) {
							newId = field.id + '.' + valueSlug;
							fields[ newId ] = {
								id: newId,
								label: fieldLabel + ' (' + valueLabel + ')',
								format: field.format,
							};
						}
					} );
				} );

				return fields;
			},

			/**
			 * Get field label with fallback.
			 *
			 * @since 1.2.0
			 * @deprecated 1.5.0
			 *
			 * @param {Object} field Field data.
			 *
			 * @return {string} Field label.
			 */
			getFieldLabel( field ) {
				// eslint-disable-next-line no-console
				console.warn( 'WARNING! Function "WPForms.Admin.Builder.Providers.Sendinblue.getFieldLabel( field )" has been deprecated.' );

				let fieldLabel = '';

				if ( ! _.has( field, 'id' ) || ! _.has( field, 'label' ) ) {
					return fieldLabel;
				}

				if ( field.label.toString().trim() !== '' ) {
					fieldLabel = wpf.sanitizeHTML( field.label.toString().trim() );
				} else {
					fieldLabel = wpforms_builder.field + ' #' + field.id;
				}

				return fieldLabel;
			},

			/**
			 * Retrieve Name field formats.
			 *
			 * @since 1.2.0
			 * @deprecated 1.5.0
			 *
			 * @param {Object} field Field data.
			 *
			 * @return {Array} Formats for Name field.
			 */
			getNameFormats( field ) {
				// eslint-disable-next-line no-console
				console.warn( 'WARNING! Function "WPForms.Admin.Builder.Providers.Sendinblue.getNameFormats( field )" has been deprecated.' );

				let formats = [];

				if ( ! _.has( field, 'format' ) || _.isEmpty( field.format ) ) {
					return formats;
				}

				formats = field.format.split( '-' );

				return _.isArray( formats ) ? formats : [];
			},

			/**
			 * Determine if it's a Name field.
			 *
			 * @since 1.2.0
			 * @deprecated 1.5.0
			 *
			 * @param {Object} field Field data.
			 *
			 * @return {boolean} True if it's a Name field, otherwise - false.
			 */
			isNameField( field ) {
				// eslint-disable-next-line no-console
				console.warn( 'WARNING! Function "WPForms.Admin.Builder.Providers.Sendinblue.isNameField( field )" has been deprecated.' );

				return ! _.isEmpty( field ) && _.has( field, 'type' ) && 'name' === field.type;
			},

			/**
			 * Update mapped selects.
			 *
			 * @since 1.2.0
			 * @deprecated 1.5.0
			 *
			 * @param {jQuery} $connections Selector with active connections.
			 * @param {Object} fields       Form fields.
			 */
			updateMapSelects( $connections, fields ) {
				// eslint-disable-next-line no-console
				console.warn( 'WARNING! Function "WPForms.Admin.Builder.Providers.Sendinblue.updateMapSelects( $connections, fields )" has been deprecated.' );

				_.each( fields, function( field ) {

					if ( ! app.helpers.isNameField( field ) ) {
						return;
					}

					var formats       = app.helpers.getNameFormats( field ),
						formatsAmount = formats.length;

					if ( formats.length > 1 ) {
						formatsAmount++;
					}

					var $optionsFormat = $( '.wpforms-builder-provider-connection-fields-table .wpforms-builder-provider-connection-fields-table-row:first option[value^="' + field.id + '."]', $connections.first() );

					// Update <option>'s label, if a `Format` setting wasn't changed.
					if ( formatsAmount && formatsAmount === $optionsFormat.length ) {
						app.helpers.updateOptionsLabel(
							$( '.wpforms-builder-provider-connection-fields-table .wpforms-builder-provider-connection-field-value option[value^="' + field.id + '."]', $connections ),
							app.helpers.getFieldLabel( field )
						);
						return;
					}

					if ( ! $optionsFormat.length ) {
						$optionsFormat = $( '.wpforms-builder-provider-connection-fields-table .wpforms-builder-provider-connection-fields-table-row:first .wpforms-builder-provider-connection-field-value option', $connections.first() );
					}

					app.helpers.updateNameFieldOptions( $connections, $optionsFormat, field );
				} );
			},

			/**
			 * Update mapped options - do some specific things for options related with Name fields.
			 *
			 * @since 1.2.0
			 * @deprecated 1.5.0
			 *
			 * @param {jQuery} $connections Selector with active connections.
			 * @param {jQuery} $options     Selector with options.
			 * @param {Object} field        Form field.
			 */
			updateNameFieldOptions( $connections, $options, field ) {
				// eslint-disable-next-line no-console
				console.warn( 'WARNING! Function "WPForms.Admin.Builder.Providers.Sendinblue.updateNameFieldOptions( $connections, $options, field )" has been deprecated.' );

				var fieldLabel   = app.helpers.getFieldLabel( field ),
					pointerValue = field.id;

				if ( ! $options.filter( '[value="' + pointerValue + '"]' ).length ) {
					pointerValue = $options.last().val();
				}

				// Watching, that a Name field in "extended" format (Full, First, Middle and Last).
				_.each( wpformsSendinblueBuilderVars.l10n.nameFieldFormats, function( valueLabel, valueSlug ) {

					var optionValue       = field.id + '.' + valueSlug, // e.g., 1.first
						$optionFormatItem = $options.filter( '[value="' + optionValue + '"]' );

					if ( ( -1 === field.format.indexOf( valueSlug ) ) && ( 'full' !== valueSlug ) ) {

						// Remove <option>'s with format, which a Name field doesn't support.
						if ( $optionFormatItem.length ) {
							$( '.wpforms-builder-provider-connection-fields-table .wpforms-builder-provider-connection-field-value option[value="' + optionValue + '"]', $connections ).remove();
						}
						return;
					}

					// Update <option> label with format, if it's already exists.
					if ( $optionFormatItem.length ) {
						pointerValue = optionValue;
						app.helpers.updateOptionsLabel( $optionFormatItem, fieldLabel );
						return;
					}

					// Add a new <option>.
					$( '.wpforms-builder-provider-connection-fields-table .wpforms-builder-provider-connection-field-value option[value="' + pointerValue + '"]', $connections ).after(
						$( '<option>', {
							text: wpf.sanitizeHTML( fieldLabel + ' (' + valueLabel + ')' ),
							value: optionValue,
						} )
					);
					pointerValue = optionValue;
				} );

				// Remove <option>'s for Name fields without format.
				$( '.wpforms-builder-provider-connection-fields-table .wpforms-builder-provider-connection-field-value option[value="' + field.id + '"]', $connections ).remove();
			},

			/**
			 * Update label/text for mapped select options.
			 *
			 * @since 1.2.0
			 * @deprecated 1.5.0
			 *
			 * @param {jQuery} $options   Selector with options.
			 * @param {string} fieldLabel Field label.
			 */
			updateOptionsLabel( $options, fieldLabel ) {
				// eslint-disable-next-line no-console
				console.warn( 'WARNING! Function "WPForms.Admin.Builder.Providers.Sendinblue.updateOptionsLabel( $options, fieldLabel )" has been deprecated.' );

				_.each( $options, function( option ) {

					var $option  = $( option ),
						value    = $option.val(),
						label    = $option.text(),
						data     = value.split( '.' ),
						newLabel = fieldLabel,
						valueSlug;

					if ( ! _.isArray( data ) || data.length < 2 ) {
						return;
					}

					valueSlug = data[1];

					if ( _.has( wpformsSendinblueBuilderVars.l10n.nameFieldFormats, valueSlug ) ) {
						newLabel += ' (' + wpformsSendinblueBuilderVars.l10n.nameFieldFormats[ valueSlug ] + ')';
					}

					if ( label !== newLabel ) {
						$option.text( newLabel );
					}
				} );
			},
		},
	};

	// Provide access to public functions/properties.
	return app;
}( document, window, jQuery ) );

// Initialize.
WPForms.Admin.Builder.Providers.Sendinblue.init();