403Webshell
Server IP : 65.109.86.83  /  Your IP : 37.27.51.148
Web Server : nginx/1.14.1
System : Linux libra 4.18.0-553.51.1.el8_10.x86_64 #1 SMP Wed Apr 30 20:24:04 UTC 2025 x86_64
User : root ( 0)
PHP Version : 8.3.31
Disable Function : exec,passthru,shell_exec,system,proc_open,popen,parse_ini_file,show_source
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /var/www/html/wp-content/plugins/thrive-leads/inc/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/wp-content/plugins/thrive-leads/inc/helpers.php
<?php

/**
 * appends the WordPress tables prefix and the default tve_leads prefix to the table name
 *
 * @param string $table
 *
 * @return string the modified table name
 */
function tve_leads_table_name( $table ) {
	global $wpdb;

	return $wpdb->prefix . TVE_LEADS_DB_PREFIX . $table;
}

/**
 * return a list with all available form types
 * the keys in the array are internally used codes, and the values are the translations of the form type names
 *
 * @param bool $include_extra whether or not to include the shortcode type and 2-step type in the returned result
 *
 * @return array
 */
function tve_leads_get_default_form_types( $include_extra = false ) {
	$main = array(
		'in_content'    => array(
			'post_title'    => __( 'In content', 'thrive-leads' ),
			'tve_form_type' => 'in_content',
			'edit_selector' => '.thrv-leads-in-content', // selector for the element settings in editing mode
			'wp_hook'       => 'the_content',
			'priority'      => 20,
			'video_link'    => '9YS9EGUel98',
		),
		'lightbox'      => array(
			'post_title'    => __( 'Lightbox', 'thrive-leads' ),
			'tve_form_type' => 'lightbox',
			'edit_selector' => '.tve_p_lb_control', // selector for the element settings in editing mode
			'wp_hook'       => 'wp_footer',
			'video_link'    => '2SXwMnfIFXc',
		),
		'post_footer'   => array(
			'post_title'    => __( 'Post footer', 'thrive-leads' ),
			'tve_form_type' => 'post_footer',
			'edit_selector' => '.thrv-leads-form-box', // selector for the element settings in editing mode
			'wp_hook'       => 'the_content',
			'video_link'    => 'J9Tt42ts43s',
		),
		'ribbon'        => array(
			'post_title'    => __( 'Ribbon', 'thrive-leads' ),
			'tve_form_type' => 'ribbon',
			'edit_selector' => '.thrv-ribbon', // selector for the element settings in editing mode
			'wp_hook'       => 'wp_footer',
			'video_link'    => 'x8QGGaqxPDY',
		),
		'screen_filler' => array(
			'post_title'    => __( 'Screen filler lightbox', 'thrive-leads' ),
			'tve_form_type' => 'screen_filler',
			'edit_selector' => '.thrv-leads-screen-filler', // selector for the element settings in editing mode
			'wp_hook'       => 'wp_footer',
			'video_link'    => 'IdvjD6T4Xa4',
		),
		'greedy_ribbon' => array(
			'post_title'    => __( 'Scroll mat', 'thrive-leads' ),
			'tve_form_type' => 'greedy_ribbon',
			'edit_selector' => '.thrv-greedy-ribbon', // selector for the element settings in editing mode
			'wp_hook'       => 'wp_footer',
			'video_link'    => '4UHtgN8LZzI',
		),
		'slide_in'      => array(
			'post_title'    => __( 'Slide in', 'thrive-leads' ),
			'tve_form_type' => 'slide_in',
			'edit_selector' => '.thrv-leads-slide-in', // selector for the element settings in editing mode
			'wp_hook'       => 'wp_footer',
			'video_link'    => 'dhL4NEt84kk',
		),
		'widget'        => array(
			'post_title'    => __( 'Widget', 'thrive-leads' ),
			'edit_selector' => '.thrv-leads-widget', // selector for the element settings in editing mode
			'tve_form_type' => 'widget',
			'video_link'    => 'uSrD8lVbF5Q',
		),
		/**
		 * no wp_hook for php_inserts, these are to be added by the (advanced) user - as pieces of PHP code that can be directly inserted into
		 * the theme / sidebar etc
		 */
		'php_insert'    => array(
			'post_title'    => __( 'PHP Insert', 'thrive-leads' ),
			'tve_form_type' => 'php_insert',
			'edit_selector' => '.thrv-leads-form-box',
		),
	);

	if ( $include_extra ) {
		$main['shortcode'] = array(
			'post_title'    => __( 'Shortcode', 'thrive-leads' ),
			'tve_form_type' => 'shortcode',
			'edit_selector' => '.thrv-leads-form-box', // selector for the element settings in editing mode
			'wp_hook'       => '',
		);

		$main['two_step_lightbox'] = array(
			'post_title'    => __( 'ThriveBox', 'thrive-leads' ),
			'tve_form_type' => 'two_step_lightbox',
			'edit_selector' => '.tve_p_lb_control', // selector for the element settings in editing mode
			'wp_hook'       => '',
		);
	}

	return $main;
}

/**
 * prepare the default form types for the backbone application
 *
 * @return array()
 */
function tve_leads_prepare_default_form_types() {
	$types = tve_leads_get_default_form_types();

	return array_values( $types );
}

/**
 * return a formatted conversion rate based on $impressions and $conversions
 *
 * @param int $impressions
 * @param int $conversions
 * @param string $suffix
 * @param string $decimals
 * @param string $if_zero what to return if either of the values is 0
 *
 * @return string $rate the calculated conversion rate
 */
function tve_leads_conversion_rate( $impressions, $conversions, $suffix = '%', $decimals = '2', $if_zero = 'N/A' ) {
	$impressions = (int) $impressions;
	$conversions = (int) $conversions;
	if ( $conversions == 0 || $impressions == 0 ) {
		// For chart data, return 0 instead of 'N/A' when suffix is empty
		if ( empty( $suffix ) ) {
			return 0;
		}
		return $if_zero;
	}

	$rate = round( 100 * ( $conversions / $impressions ), $decimals );
	
	// Return numeric value when no suffix is requested (for charts)
	if ( empty( $suffix ) ) {
		return (float) $rate;
	}
	
	return $rate . $suffix;
}

/**
 * get the configuration array for a specific editor template for a form variation
 *
 * @param string $key
 *
 * @return array
 */
function tve_leads_get_editor_template_config( $key ) {
	if ( strpos( $key, '|' ) === false ) {
		return array();
	}
	list( $type, $key ) = explode( '|', $key );

	if ( $key === 'tcb2_blank' ) {
		return tve_leads_get_v2_blank_config( $type );
	}

	$config = require dirname( dirname( __FILE__ ) ) . '/editor-templates/_config.php';

	$type = Thrive_Leads_Template_Manager::tpl_type_map( $type );

	$cloud_config = tve_leads_get_downloaded_templates( $type );

	if ( ! empty( $cloud_config ) ) {
		$config[ $type ] = array_merge_recursive( $config[ $type ], $cloud_config );
	}

	if ( isset( $config[ $type ][ $key ] ) && isset( $config[ $type ][ $key ]['fonts'] ) && tve_dash_is_google_fonts_blocked() ) {
		// Replace Google Fonts with Bunny Fonts instead of removing them
		$config[ $type ][ $key ]['fonts'] = array_map( 'tve_replace_google_font_with_bunny', $config[ $type ][ $key ]['fonts'] );
	}

	return isset( $config[ $type ][ $key ] ) ? $config[ $type ][ $key ] : array();
}

/**
 * get configuration for a specific variation (form) type
 *
 * @param string $variation_type ribbon, lightbox etc
 *
 * @return array
 */
function tve_leads_get_editor_template_type_config( $variation_type ) {
	$config         = require dirname( dirname( __FILE__ ) ) . '/editor-templates/_config.php';
	$variation_type = Thrive_Leads_Template_Manager::tpl_type_map( $variation_type );

	$cloud_config = tve_leads_get_downloaded_templates( $variation_type );

	if ( ! empty( $cloud_config ) ) {
		$config[ $variation_type ] = array_merge_recursive( $config[ $variation_type ], $cloud_config );
	}

	return isset( $config[ $variation_type ] ) ? $config[ $variation_type ] : array();
}

/**
 *
 * get the TCB editor EDIT URL for a form variation
 *
 * @param int $post_id
 * @param int $variation_key
 *
 * @return string the url to open the editor for this variation
 */
function tve_leads_get_editor_url( $post_id, $variation_key, $escape = true ) {
	$editor_link = set_url_scheme( get_edit_post_link( $post_id, '' ) );
	$editor_link = add_query_arg( array(
		'tve'    => 'true',
		'_key'   => $variation_key,
		'r'      => uniqid(),
		'action' => 'architect',
	), $editor_link );

	if ( $escape ) {
		$editor_link = esc_url( $editor_link );
	}

	/**
	 * we need to make sure that if the admin is https, then the editor link is also https, otherwise any ajax requests through wp ajax api will not work
	 */
	$admin_ssl = strpos( admin_url(), 'https' ) === 0;

	return $admin_ssl ? str_replace( 'http://', 'https://', $editor_link ) : $editor_link;
}

/**
 * get the TCB editor PREVIEW URL for a form variation
 *
 * @param int $post_id
 * @param int $variation_key
 * @param boolean escape
 *
 * @return string the url to open the editor for this variation
 */
function tve_leads_get_preview_url( $post_id, $variation_key, $escape = true ) {
	//$cache = isset( $GLOBALS['TVE_LEADS_CACHE_PERMALINKS'] ) ? $GLOBALS['TVE_LEADS_CACHE_PERMALINKS'] : array();
	$cache = array(); //reset cache cos it has only editor links
	if ( ! isset( $cache[ $post_id ] ) ) {
		$cache[ $post_id ]                     = set_url_scheme( get_permalink( $post_id ) );
		$GLOBALS['TVE_LEADS_CACHE_PERMALINKS'] = $cache;
	}
	/*
	 * We need the post to complete the full arguments
	 */
	$post        = get_post( $post_id );
	$editor_link = $cache[ $post_id ];
	$editor_link = apply_filters( 'preview_post_link', add_query_arg( array(
		'_key' => $variation_key,
		'r'    => uniqid()
	), $editor_link ), $post );

	if ( $escape ) {
		$editor_link = esc_url( $editor_link );
	}

	return $editor_link;
}

/**
 * generate a random number between 0 and $total-1
 *
 * @param int $total
 * @param int $multiplier for smaller values, it's better to extend the interval by a number of times,
 *                        example: to choose between 0 and 1 -> we think it's better to have a random number between 0 and 10000 and split that into halves
 *
 * @return int
 */
function tve_leads_get_random_index( $total, $multiplier = 1000 ) {
	$_rand = function_exists( 'mt_rand' ) ? mt_rand( 0, $total * $multiplier - 1 ) : rand( 0, $total * $multiplier - 1 );

	return intval( floor( $_rand / $multiplier ) );
}

/**
 * get a list of all available triggers (optional) grouped by a specific form type
 *
 * @param string|null $form_type , if present, it will only return triggers that apply to that specific form type
 *
 * @param bool $get_as_array whether or not to get the results as array instead of Trigger objects
 *
 * @return array the list of triggers
 */
function tve_leads_get_available_triggers( $form_type = null, $get_as_array = false ) {
	$return = array();
	foreach ( TVE_Leads_Trigger_Abstract::$AVAILABLE as $trigger ) {
		$item = TVE_Leads_Trigger_Abstract::factory( $trigger );
		if ( ! $item ) {
			continue;
		}
		if ( $form_type && ! $item->appliesTo( $form_type ) ) {
			continue;
		}
		$return[ $trigger ] = $get_as_array ? $item->to_array() : $item;
	}

	return $return;
}

/**
 * get a list of all available animations (optional) grouped by a specific form type
 *
 * @param bool $get_as_array whether or not to get the results as array instead of Animation objects
 *
 * @return array the list of animations
 */
function tve_leads_get_available_animations( $get_as_array = false ) {
	$return = array();
	foreach ( TVE_Leads_Animation_Abstract::$available as $animation ) {
		$item = TVE_Leads_Animation_Abstract::factory( $animation );
		if ( ! $item ) {
			continue;
		}

		$return[ $animation ] = $get_as_array ? $item->get_title() : $item;
	}

	return $return;
}

/**
 * get a list of all available positions
 *
 * @param String $form_type
 *
 * @return array the list of positions
 */
function tve_leads_get_available_positions( $form_type ) {
	switch ( $form_type ) {
		case 'slide_in':
			return array(
				'label'    => __( 'Position', 'thrive-leads' ),
				'position' => array(
					'bot_left'  => __( 'Bottom Left', 'thrive-leads' ),
					'bot_right' => __( 'Bottom Right', 'thrive-leads' ),
					'top_left'  => __( 'Top Left', 'thrive-leads' ),
					'top_right' => __( 'Top Right', 'thrive-leads' ),
				),
			);
		case 'ribbon':
			return array(
				'label'    => __( 'Position', 'thrive-leads' ),
				'position' => array(
					'above'  => __( 'Top over content', 'thrive-leads' ),
					'top'    => __( 'Top', 'thrive-leads' ),
					'bottom' => __( 'Bottom', 'thrive-leads' ),
				),
			);
		case 'in_content':
			return array(
				'label'    => __( 'Show after how many paragraphs?', 'thrive-leads' ),
				'position' => array(
					0  => 0,
					1  => 1,
					2  => 2,
					3  => 3,
					4  => 4,
					5  => 5,
					6  => 6,
					7  => 7,
					8  => 8,
					9  => 9,
					10 => 10
				),
			);
		default:
			return array();
	}
}

/**
 * get a unique cookie key based on a form that's being displayed now
 *
 * @param        $main_group
 * @param        $form_type
 * @param        $variation
 * @param string $type
 *
 * @return string
 */
function tve_leads_get_form_cookie_key( $main_group, $form_type, $variation, $type = 'impression' ) {

	$group_id      = is_object( $main_group ) ? $main_group->ID : $main_group;
	$form_type_id  = is_object( $form_type ) ? $form_type->ID : $form_type;
	$variation_key = is_array( $variation ) ? $variation['key'] : $variation;

	$key = 'tl' . ( $type ? '_' . $type : '' );
	if ( $group_id ) {
		$key .= '_' . $group_id;
	}
	if ( $form_type_id ) {
		$key .= '_' . $form_type_id;
	}
	$key .= '_' . $variation_key;

	return $key;
}

/**
 * flush and send the output buffer, for faster responses during the form submit
 * headers and some data are send and after this the main processing of data can be done without users knowing the difference
 *
 * thanks to http://stackoverflow.com/questions/10579116/how-to-flush-data-to-browser-but-continue-executing
 */
function tve_leads_send_output() {
	ob_start();

	/* generate some dummy output */
	echo '1' . str_pad( '', 4096 ) . "\n";

	/* Ignore connection-closing by the client */
	ignore_user_abort( true );

	/* send the contents */
	$content = ob_get_contents();        // Get the content of the output buffer
	ob_end_clean();                      // Close current output buffer
	$len = strlen( $content );             // Get the length
	header( 'Connection: close' );         // Tell the client to close connection
	header( "Content-Length: $len" );      // Close connection after $size characters
	echo $content;                       // Output content
	flush();                             // Force php-output-cache to flush to browser.

	// Kill all other output buffering
	while ( ob_get_level() > 0 ) {
		ob_end_clean();
	}
}

/**
 * Calculate the chance of a variation to beat the original during a test
 *
 * @param $variation_conversion_rate
 * @param $variation_unique_impressions
 * @param $control_conversion_rate
 * @param $control_unique_impressions
 *
 * @return string $confidence_level
 */
function tve_leads_test_item_beat_original(
	$variation_conversion_rate, $variation_unique_impressions, $control_conversion_rate, $control_unique_impressions, $suffix = '%'
) {
	if ( $variation_unique_impressions == 0 || $control_unique_impressions == 0 || ! is_numeric( $variation_conversion_rate ) || ! is_numeric( $control_conversion_rate ) ) {
		return 'N/A';
	}

	$variation_conversion_rate = $variation_conversion_rate / 100;
	$control_conversion_rate   = $control_conversion_rate / 100;

	//standard deviation = sqrt((conversionRate*(1-conversionRate)/uniqueImpressions)
	$variation_standard_deviation = sqrt( ( $variation_conversion_rate * ( 1 - $variation_conversion_rate ) / $variation_unique_impressions ) );
	$control_standard_deviation   = sqrt( ( $control_conversion_rate * ( 1 - $control_conversion_rate ) / $control_unique_impressions ) );

	if ( ( $variation_standard_deviation == 0 && $control_standard_deviation == 0 ) || ( is_nan( $variation_standard_deviation ) || is_nan( $control_standard_deviation ) ) ) {
		return 'N/A';
	}
	//z-score = (control_conversion_rate - variation_conversion_rate) / sqrt((controlStandardDeviation^2)+(variationStandardDeviation^2))
	$z_score = ( $control_conversion_rate - $variation_conversion_rate ) / sqrt( pow( $control_standard_deviation, 2 ) + pow( $variation_standard_deviation, 2 ) );

	if ( is_nan( $z_score ) ) {
		return 'N/A';
	}

	//Confidence_level (which is synonymous with “chance to beat original”)  = normdist(z-score)
	$confidence_level = tve_leads_norm_dist( $z_score );

	return number_format( round( ( 1 - $confidence_level ) * 100, 2 ), 2 ) . $suffix;
}

/**
 * Function that will generate a cumulative normal distribution and return the confidence level as a number between 0 and 1
 *
 * @param $x
 *
 * @return float
 */
function tve_leads_norm_dist( $x ) {
	$b1 = 0.319381530;
	$b2 = - 0.356563782;
	$b3 = 1.781477937;
	$b4 = - 1.821255978;
	$b5 = 1.330274429;
	$p  = 0.2316419;
	$c  = 0.39894228;

	if ( $x >= 0.0 ) {
		if ( ( 1.0 + $p * $x ) == 0 ) {
			return 'N/A';
		}
		$t = 1.0 / ( 1.0 + $p * $x );

		return ( 1.0 - $c * exp( - $x * $x / 2.0 ) * $t * ( $t * ( $t * ( $t * ( $t * $b5 + $b4 ) + $b3 ) + $b2 ) + $b1 ) );
	} else {
		if ( ( 1.0 - $p * $x ) == 0 ) {
			return 'N/A';
		}
		$t = 1.0 / ( 1.0 - $p * $x );

		return ( $c * exp( - $x * $x / 2.0 ) * $t * ( $t * ( $t * ( $t * ( $t * $b5 + $b4 ) + $b3 ) + $b2 ) + $b1 ) );
	}
}

/**
 * Generate error message HTML for shortcode rendering errors.
 *
 * @param string $error_type The error type constant (TVE_LEADS_ERROR_NO_CONTENT, TVE_LEADS_ERROR_NO_FORMS, etc.)
 *
 * @return string HTML for the error message
 */
function tve_leads_get_shortcode_error_html( $error_type ) {
	$error_message = '';

	switch ( $error_type ) {
		case TVE_LEADS_ERROR_NO_CONTENT:
			$error_message = __( 'We couldn\'t load anything for this Lead Shortcode because the form doesn\'t have any form design. Design the form for this shortcode in Thrive Leads, and it will automatically appear here.', 'thrive-leads' );
			break;
		case TVE_LEADS_ERROR_NO_FORMS:
			$error_message = __( 'We couldn\'t load anything for this Lead Shortcode because there are no forms under it. Create a form for this shortcode in Thrive Leads, and it will automatically appear here.', 'thrive-leads' );
			break;
		default:
			$error_message = __( 'Shortcode could not be rendered!', 'thrive-leads' );
			break;
	}

	// Note: Using inline SVG because this content is rendered via AJAX/shortcode and the SVG sprite isn't available.
	$warning_icon = '<svg class="tve-leads-shortcode-error__icon" xmlns="http://www.w3.org/2000/svg" width="23" height="20" viewBox="0 0 23 20" fill="none"><path d="M11.4397 0C12.0647 -5.46392e-08 12.6451 0.357143 12.9576 0.892857L22.6004 17.3214C22.9129 17.9018 22.9129 18.5714 22.6004 19.1071C22.2879 19.6875 21.7076 20 21.0826 20L1.79688 20C1.12723 20 0.546875 19.6875 0.234375 19.1071C-0.078125 18.5714 -0.078125 17.9018 0.234375 17.3214L9.87723 0.892857C10.1897 0.357143 10.7701 5.8542e-08 11.4397 0ZM11.4397 5.71429C10.8147 5.71429 10.3683 6.20536 10.3683 6.78571V11.7857C10.3683 12.4107 10.8147 12.8571 11.4397 12.8571C12.0201 12.8571 12.5112 12.4107 12.5112 11.7857V6.78571C12.5112 6.20536 12.0201 5.71428 11.4397 5.71429ZM12.8683 15.7143C12.8683 14.9554 12.1987 14.2857 11.4397 14.2857C10.6362 14.2857 10.0112 14.9554 10.0112 15.7143C10.0112 16.5179 10.6362 17.1429 11.4397 17.1429C12.1987 17.1429 12.8683 16.5179 12.8683 15.7143Z" fill="#FB5C55"/></svg>';

	return '<div class="tve-leads-shortcode-error">' . $warning_icon . '<p class="tve-leads-shortcode-error__message">' . $error_message . '</p></div>';
}

/**
 * Render the form included in the shortcode
 * the received parameter should contain one element: the id of the TL shortcode
 *
 * @param array $attributes
 *
 * @return mixed the rendered form or return the array with shortcode prop
 */
function tve_leads_shortcode_render( $attributes = array() ) {
	if ( class_exists( 'PostGridHelper' ) && PostGridHelper::$render_post_grid === false ) {
		return '';
	}

	if (
		is_feed() ||
		doing_action( 'wpseo_head' ) || /* SUPP-13169 - don't load shortcodes in head while yoast changes meta tags */
		( ! empty( $_REQUEST['action'] ) && $_REQUEST['action'] === 'editpost' ) /* SUPP-14391 - yoast conflict - do not render during post save */
	) {
		return '';
	}
	// $attributes must be always array and from the parameter it can come with the empty string.
	if ( empty( $attributes ) ) {
		$attributes = array();
	}

	$defaults = array(
		'id'         => null,
		'for_editor' => false,
	);

	$content    = '';
	$attributes = array_merge( $defaults, $attributes );

	if ( empty( $attributes['for_editor'] ) && is_editor_page() ) {
		/* Case: shortcode is rendered somewhere outside the main content area - this causes TAr to take the wrong #tve_editor div as the main element */
		return tve_leads_template( 'shortcode-message', array(), true );
	}

	if ( empty( $attributes['id'] ) ) {
		return __( 'Invalid shortcode parameters', 'thrive-leads' );
	}

	$ajax_load_forms = tve_leads_get_option( 'ajax_load' );

	$shortcode = tve_leads_get_shortcode( $attributes['id'] );
	if ( ! $shortcode || $shortcode->post_status != TVE_LEADS_STATUS_PUBLISH ) {
		return '';
	}

	/**
	 * enqueue the default scripts and CSS (required for all forms)
	 */
	tve_leads_enqueue_default_scripts();

	/**
	 * hold the main shortcode ID in the page, in a javascript var to be able to load it afterwards
	 */
	$GLOBALS['tve_leads_form_config']['shortcode_ids']   = empty( $GLOBALS['tve_leads_form_config']['shortcode_ids'] ) ? array() : $GLOBALS['tve_leads_form_config']['shortcode_ids'];
	$GLOBALS['tve_leads_form_config']['shortcode_ids'][] = $attributes['id'];

	if ( get_post_meta( $attributes['id'], 'tve_leads_masonry', true ) ) {
		wp_enqueue_script( 'jquery-masonry' );
	}

	if ( ! empty( $attributes['for_editor'] ) || ! $ajax_load_forms ) {
		$variation = tve_leads_determine_variation( $shortcode, ! empty( $attributes['for_editor'] ) ); // if we render it in the TCB editor => do not use/store cookies
		if ( empty( $variation ) ) {
			if ( empty( $attributes['for_editor'] ) ) {
				return '';
			}

			$variations_filters = array(
				'tracking_data' => false, // We don't need tracking data, just the list of form variations.
			);
			// Determine the specific error type for the editor
			$variations = tve_leads_get_form_variations( $attributes['id'], $variations_filters );

			$error_type = empty( $variations ) ? TVE_LEADS_ERROR_NO_FORMS : TVE_LEADS_ERROR_NO_CONTENT;

			return array(
				'html'       => '',
				'error_type' => $error_type,
				'fonts'      => array(),
				'css'        => array(),
			);
		}
		$GLOBALS['tve_leads_detected_variation'] = $variation;
		/**
		 * prepare data for triggers
		 */
		$GLOBALS['tve_lead_shortcodes'][ $attributes['id'] ] = $variation;
	}

	$type_key = 'shortcode_' . $attributes['id'];
	if ( empty( $attributes['for_editor'] ) && $ajax_load_forms ) {
		/**
		 * return at this point, as we will load this via AJAX
		 * append just a placeholder to the $content
		 */
		$control_variation = tve_leads_get_form_variations( $attributes['id'], array(
			'tracking_data' => false,
			'get_control'   => true,
		) );

		$content .= tve_leads_get_form_placeholder( $type_key, $control_variation );

		return $content;
	}

	list( $type, $key ) = explode( '|', $variation[ TVE_LEADS_FIELD_TEMPLATE ] );
	$key = preg_replace( '#_v(\d)+#', '', $key );

	/**
	 * and the specific styles / fonts etc for this particular form variation
	 * TCB editor page -> ajax request to get the variation
	 */
	$variation_config = tve_leads_enqueue_variation_scripts( $variation );
	if ( ! empty( $attributes['for_editor'] ) ) {
		return array_merge(
			$variation_config,
			array(
				'html' => sprintf(
					'<div class="tve-leads-conversion-object" id="%s" data-tl-type="%s"><div class="tve-leads-shortcode %s tve-leads-track-%s">%s</div></div>',
					'tve_' . $key,
					$type_key,
					'tl-anim-' . $variation['display_animation'],
					$type_key,
					str_replace( array( "\n", "\r" ), '', tve_editor_custom_content( $variation ) )
				),
			)
		);
	}

	$GLOBALS['tve_leads_form_config']['forms'][ 'shortcode_' . $attributes['id'] ] = array(
		'_key'            => $variation['key'],
		'form_name'       => $variation['post_title'],
		'trigger'         => $variation['trigger'],
		'trigger_config'  => ! empty( $variation['trigger_config'] ) ? $variation['trigger_config'] : new stdClass(),
		'form_type_id'    => $attributes['id'],
		'main_group_id'   => $attributes['id'],
		'main_group_name' => get_the_title( $attributes['id'] ),
		'active_test_id'  => empty( $variation['test_model'] ) ? '' : $variation['test_model']->id,
	);

	/**
	 * register form impression
	 * the Lead_Group parameter is set to null
	 */

	$GLOBALS['tve_lead_impressions'][ 'shortcode_' . $attributes['id'] ] = array(
		'group_id'       => $attributes['id'],
		'form_type_id'   => $attributes['id'],
		'variation_key'  => $variation['key'],
		'active_test_id' => empty( $variation['test_model'] ) ? null : $variation['test_model']->id,
	);

	$content .= tve_leads_display_form_shortcode( '__return_content', tve_editor_custom_content( $variation ), $variation );

	/**
	 * we need to set the cookies inline using a <script> tag
	 */
	if ( ! empty( $variation['set_cookies'] ) ) {
		//$content .= tve_leads_inline_cookies($variation['set_cookies']);
		$GLOBALS['tve_leads_set_cookies'] = empty( $GLOBALS['tve_leads_set_cookies'] ) ? array() : $GLOBALS['tve_leads_set_cookies'];
		/**
		 * stack variation's cookies to be used later in print_footer_scripts action
		 */
		foreach ( $variation['set_cookies'] as $key => $value ) {
			$GLOBALS['tve_leads_set_cookies'][ $key ] = $value;
		}
	}

	tve_leads_display_js_impression_data( 'shortcode_' . $attributes['id'] );

	return $content;
}

/**
 * Display content locking shortcode.
 *
 * @param $attributes
 * @param $content
 *
 * @return String shortcode content
 */
function tve_leads_shortcode_lock_render( $attributes, $content ) {
	$content = do_shortcode( $content );
	if ( tve_leads_check_conversion_cookie( $attributes['id'] ) ) {
		return $content;
	}

	while ( preg_match( '#^([^<]*)</([^>]+)>#s', $content, $m, PREG_OFFSET_CAPTURE ) ) {
		$tag     = '</' . $m[2][0] . '>';
		$content = substr_replace( $content, '', $m[2][1] - 2, strlen( $tag ) ) . $tag;
	}
	$content   = force_balance_tags( $content );
	$shortcode = tve_leads_shortcode_render( $attributes );

	if ( ! isset( $GLOBALS['tve_leads_detected_variation'] ) ) {
		/**
		 * this means ajax_load is enabled - we need to output just the placeholder
		 */
		return sprintf(
			'<div class="tve_content_lock tve_lock_hide tve_lead_lock">
                <div class="tve_lead_lock_shortcode">%s</div>
                <div class="tve_lead_locked_content"><div class="tve_lead_locked_overlay"></div>%s</div>
            </div>',
			$shortcode,
			$content
		);
	}

	$variation = $GLOBALS['tve_leads_detected_variation'];

	$main_class = isset( $variation['display_animation'] ) && $variation['display_animation'] === 'blur' ? 'tve_lock_blur' : 'tve_lock_hide';

	$html = sprintf(
		'<div class="tve_content_lock %s tve_lead_lock">
            <div class="tve_lead_lock_shortcode">%s</div>
            <div class="tve_lead_locked_content"><div class="tve_lead_locked_overlay"></div>%s</div>
        </div>',
		$main_class,
		$shortcode,
		$content
	);

	return $html;
}

/**
 * Render the button / link etc contents that will trigger the opening of the lightbox
 * register the lightbox to be output in the footer (or just a placeholder in case AJAX-loading of forms is enabled)
 *
 * @param array $attributes
 * @param string $content
 *
 * @return string
 */
function tve_leads_two_step_render( $attributes, $content ) {
	if ( empty( $attributes['id'] ) ) {
		return __( 'Invalid shortcode attributes', 'thrive-leads' );
	}
	/**
	 * Filter to check if we want to show the two step lightbox
	 *
	 * @param $attributes ['id'] - the id of the two step lightbox
	 */
	if ( apply_filters( 'tve_leads_do_not_show_two_step', false, $attributes['id'] ) ) {
		return '';
	}

	$two_step = tve_leads_get_form_type( $attributes['id'], array( 'get_variations' => false ) );
	if ( ! $two_step || $two_step->post_status != TVE_LEADS_STATUS_PUBLISH ) {
		return '';
	}

	$ajax_load_forms = tve_leads_get_option( 'ajax_load' );

	if ( ! $ajax_load_forms ) {
		$variation = tve_leads_determine_variation( $two_step );
		if ( empty( $variation ) ) {
			return __( 'No form found', 'thrive-leads' );
		}

		/* If the subscribed state is hidden, we don't display the trigger for the two step lightbox */
		$already_subscribed_html = tve_leads_get_already_subscribed_html( $variation, 'lightbox', true );
		if ( $already_subscribed_html === TVE_ALREADY_SUBSCRIBED_HIDDEN ) {
			return '';
		}
	}

	/**
	 * hold the main shortcode ID in the page, in a javascript var to be able to load it afterwards
	 */
	$GLOBALS['tve_leads_form_config']['two_step_ids']   = empty( $GLOBALS['tve_leads_form_config']['two_step_ids'] ) ? array() : $GLOBALS['tve_leads_form_config']['two_step_ids'];
	$exists_on_page                                     = in_array( $attributes['id'], $GLOBALS['tve_leads_form_config']['two_step_ids'] );
	$GLOBALS['tve_leads_form_config']['two_step_ids'][] = $attributes['id'];

	/**
	 * enqueue the default scripts and CSS (required for all forms)
	 */
	tve_leads_enqueue_default_scripts();

	if ( get_post_meta( $attributes['id'], 'tve_leads_masonry', true ) ) {
		wp_enqueue_script( 'jquery-masonry' );
	}

	if ( $ajax_load_forms ) {
		$GLOBALS['tve_leads_footer_html'] = empty( $GLOBALS['tve_leads_footer_html'] ) ? '' : $GLOBALS['tve_leads_footer_html'];
		if ( ! $exists_on_page ) {
			$GLOBALS['tve_leads_footer_html'] .= sprintf( '<span style="display:none" class="tl-placeholder-f-type-%s"></span>', 'two_step_' . $attributes['id'] );
		}

		return sprintf(
			'<span class="tve-leads-two-step-trigger tl-2step-trigger-%s">%s</span>',
			$attributes['id'],
			do_shortcode( $content )
		);
	}

	$variation['trigger']        = 'click';
	$variation['trigger_config'] = array( 'c' => 'tl-2step-trigger-' . $attributes['id'] );

	/**
	 * prepare data for triggers
	 */
	$GLOBALS['tve_leads_two_step'][ $variation['key'] ] = $variation;

	/**
	 * and the specific styles / fonts etc for this particular form variation
	 */
	tve_leads_enqueue_variation_scripts( $variation );

	/**
	 * append javascript needed for triggers to the global JS variable
	 */
	$GLOBALS['tve_leads_form_config']['forms'][ 'two_step_' . $attributes['id'] ] = array(
		'_key'            => $variation['key'],
		'form_name'       => $variation['post_title'],
		'trigger'         => 'click', // ALWAYS click
		'trigger_config'  => array( 'c' => 'tl-2step-trigger-' . $attributes['id'] ),
		'form_type_id'    => $attributes['id'],
		'main_group_id'   => $attributes['id'],
		'main_group_name' => get_the_title( $attributes['id'] ),
		'active_test_id'  => ! empty( $variation['test_model'] ) ? $variation['test_model']->id : null,
	);

	$GLOBALS['tve_leads_two_step'][ $variation['key'] ]['form_output'] = tve_editor_custom_content( $variation );

	$type = 'two_step_' . $attributes['id'];

	$GLOBALS['tve_lead_impressions'][ 'two_step_' . $attributes['id'] ] = array(
		'group_id'       => $two_step->ID,
		'form_type_id'   => $two_step->ID,
		'variation_key'  => $variation['key'],
		'active_test_id' => ! empty( $variation['test_model'] ) ? $variation['test_model']->id : null,
	);

	$content = sprintf(
		'<span class="tve-leads-two-step-trigger tl-2step-trigger-%s">%s</span>',
		$attributes['id'],
		do_shortcode( $content )
	);

	/**
	 * we need to set the cookies inline using a <script> tag
	 */
	if ( ! empty( $variation['set_cookies'] ) ) {
		//$content .= tve_leads_inline_cookies($variation['set_cookies']);
		$GLOBALS['tve_leads_set_cookies'] = empty( $GLOBALS['tve_leads_set_cookies'] ) ? array() : $GLOBALS['tve_leads_set_cookies'];
		/**
		 * stack variation's cookies to be used later in print_footer_scripts action
		 */
		foreach ( $variation['set_cookies'] as $key => $value ) {
			$GLOBALS['tve_leads_set_cookies'][ $key ] = $value;
		}
	}

	/**
	 * Do NOT call tve_leads_display_js_impression_data() for two-step lightboxes (ThriveBox).
	 * Impressions should only be tracked when the ThriveBox is actually opened (triggered by click),
	 * not on page load. The impression tracking is handled in frontend.js when open_two_step_lightbox is called.
	 *
	 * @see https://github.com/awesomemotive/thrive-themes/issues/2504
	 */

	return $content;

}

/**
 * get a human-friendly name for the trigger setup in $variation, based on trigger and trigger_config fields
 *
 * @param array $variation
 *
 * @return String
 */
function tve_leads_trigger_nice_name( $variation ) {
	$trigger = TVE_Leads_Trigger_Abstract::factory( $variation['trigger'], $variation['trigger_config'] );

	return $trigger ? $trigger->get_display_name() : '';
}

/**
 * check if there is a valid activated license for the TL plugin
 *
 * @return bool
 */
function tve_leads_license_activated() {
	return TVE_Dash_Product_LicenseManager::getInstance()->itemActivated( TVE_Dash_Product_LicenseManager::TL_TAG );
}

/**
 * check if the current TCB version is the one required by Thrive Leads
 *
 * @return bool
 */
function tve_leads_check_tcb_version() {
	if ( ! tve_in_architect() ) { // the internal TCB code will always be up to date
		return true;
	}

	$internal_architect_version = include TVE_LEADS_PATH . '/tcb/version.php';

	/* make sure that the we have the same version of architect inside the plugin and as individual plugin, otherwise conflicts can appear */
	if ( ! defined( 'TVE_VERSION' ) || ! version_compare( TVE_VERSION, $internal_architect_version, '=' ) ) {
		return false;
	}

	return true;
}

/**
 * show a box with a warning message and a link to take the user to the license activation page
 * this will be called only when no valid / activated license has been found
 *
 * @return mixed
 */
function tve_leads_license_warning() {
	return include dirname( dirname( __FILE__ ) ) . '/admin/views/license_inactive.php';
}

/**
 * show a box with a warning message notifying the user to update the TCB plugin to the latest version
 * this will be shown only when the TCB version is lower than a minimum required version
 */
function tve_leads_tcb_version_warning() {
	return include dirname( dirname( __FILE__ ) ) . '/admin/views/tcb_version_incompatible.php';
}

/**
 * returns whether or not a form_type allows frequency settings - how many days should pass before displaying it in the same browser
 *
 * @param int|WP_Post $form_type
 *
 * @return bool
 */
function tve_leads_form_type_has_frequency_settings( $form_type ) {
	if ( is_null( $form_type ) ) {
		return false;
	}

	if ( is_numeric( $form_type ) ) {
		$form_type = tve_leads_get_form_type( $form_type );
	}

	if ( is_object( $form_type ) ) {
		if ( empty( $form_type->tve_form_type ) ) {
			return false;
		}
		$form_type = $form_type->tve_form_type;
	}

	if ( empty( $form_type ) ) {
		return false;
	}

	return in_array( $form_type, array(
		'ribbon',
		'slide_in',
		'lightbox',
		'screen_filler',
		'greedy_ribbon',
	) );
}

/**
 * returns whether or not a form_type allows position settings
 * currently, position are enabled just for slide in
 *
 * @param int|WP_Post $form_type
 *
 * @return bool
 */
function tve_leads_form_type_has_position_settings( $form_type ) {
	if ( is_null( $form_type ) ) {
		return false;
	}

	if ( is_numeric( $form_type ) ) {
		$form_type = tve_leads_get_form_type( $form_type );
	}

	if ( is_object( $form_type ) ) {
		if ( empty( $form_type->tve_form_type ) ) {
			return false;
		}
		$form_type = $form_type->tve_form_type;
	}

	if ( empty( $form_type ) ) {
		return false;
	}

	return in_array( $form_type, array(
		'slide_in',
		'ribbon',
		'in_content',
	) );
}

/**
 * returns whether or not a form_type allows animation settings
 * currently, animations are enabled just for lightboxes and screen fillers
 *
 * @param int|WP_Post $form_type
 *
 * @return bool
 */
function tve_leads_form_type_has_animation_settings( $form_type ) {
	if ( is_null( $form_type ) ) {
		return false;
	}

	if ( is_numeric( $form_type ) ) {
		$form_type = tve_leads_get_form_type( $form_type );
	}

	if ( is_object( $form_type ) ) {
		if ( empty( $form_type->tve_form_type ) ) {
			return false;
		}
		$form_type = $form_type->tve_form_type;
	}

	if ( empty( $form_type ) ) {
		return false;
	}

	return in_array( $form_type, array(
		'lightbox',
		'screen_filler',
	) );
}

/**
 * returns whether a form_type allows trigger settings
 * currently, trigger settings are enabled for all form types, except for the Scroll mat form type
 *
 * @param int|WP_Post $form_type
 *
 * @return bool
 */
function tve_leads_form_type_has_trigger_settings( $form_type ) {
	if ( is_null( $form_type ) ) {
		return false;
	}

	if ( is_numeric( $form_type ) ) {
		$form_type = tve_leads_get_form_type( $form_type );
	}

	if ( is_object( $form_type ) ) {
		if ( empty( $form_type->tve_form_type ) ) {
			return false;
		}
		$form_type = $form_type->tve_form_type;
	}

	if ( empty( $form_type ) ) {
		return false;
	}

	return ! in_array( $form_type, array( 'greedy_ribbon' ) );
}

/**
 * get a human-friendly name for the Display Frequency setup for the $variation
 *
 * @param array $variation
 *
 * @return String
 */
function tve_leads_frequency_nice_name( $variation ) {
	return (int) $variation['display_frequency'] == 0
		?
		__( 'All the time', 'thrive-leads' )
		:
		sprintf( _n( 'Every %s day', 'Every %s days', $variation['display_frequency'], 'thrive-leads' ), $variation['display_frequency'] );
}

/**
 * get a human-friendly name for the Position setup for the $variation
 *
 * @param array $variation
 *
 * @return String
 */
function tve_leads_position_nice_name( $variation ) {
	switch ( $variation['position'] ) {
		case 'bot_right':
			return __( 'Bottom Right', 'thrive-leads' );
		case 'bot_left':
			return __( 'Bottom Left', 'thrive-leads' );
		case 'top_left':
			return __( 'Top Left', 'thrive-leads' );
		case 'top_right':
			return __( 'Top Right', 'thrive-leads' );
		case 'top':
			return __( 'Top', 'thrive-leads' );
		case 'above':
			return __( 'Top over content', 'thrive-leads' );
		case 'bottom':
			return __( 'Bottom', 'thrive-leads' );
		default:
			if ( is_numeric( $variation['position'] ) ) {
				if ( $variation['position'] == '0' ) {
					return __( 'At the beginning of the post', 'thrive-leads' );
				} elseif ( $variation['position'] == '1' ) {
					return __( 'After the first paragraph', 'thrive-leads' );
				} else {
					return __( 'After ' . $variation['position'] . ' paragraphs', 'thrive-leads' );
				}
			} else {
				return $variation['position'];
			}
	}

}

/**
 * get a human-friendly name for the Display Animation setup for the $variation
 *
 * @param array $variation
 *
 * @return String
 */
function tve_leads_animation_nice_name( $variation ) {
	$animation = TVE_Leads_Animation_Abstract::factory( $variation['display_animation'] );

	return $animation == null ? $variation['display_animation'] : $animation->get_translatable_title();
}

/**
 * get the default display frequency based on $form_type
 *
 * @param string $form_type
 *
 * @return int
 */
function tve_leads_get_default_display_frequency( $form_type ) {
	switch ( $form_type ) {
		case 'lightbox':
		case 'screen_filler':
		case 'slide_in':
			return 7;
		default:
			return 0;
	}
}

/**
 * get the default display frequency based on $form_type
 *
 * @param string $form_type
 *
 * @return int
 */
function tve_leads_get_default_position( $form_type ) {
	switch ( $form_type ) {
		case 'slide_in':
			return 'bot_right';
		case 'ribbon':
			return 'top';
		case 'in_content':
			return 2;
		default:
			return 'bot_right';
	}
}


/**
 * get the default display animation based on $form_type
 *
 * @param string $form_type
 *
 * @return int
 */
function tve_leads_get_default_animation( $form_type ) {
	switch ( $form_type ) {
		case 'ribbon':
			return TVE_Leads_Animation_Abstract::ANIM_SLIDE_IN_TOP;
			break;
		case 'lightbox':
		case 'screen_filler':
			return TVE_Leads_Animation_Abstract::ANIM_ZOOM_IN;
			break;
		case 'widget':
		case 'post_footer':
		case 'in_content':
		case 'shortcode':
			return TVE_Leads_Animation_Abstract::ANIM_INSTANT;
			break;
		case 'slide_in':
			return TVE_Leads_Animation_Abstract::ANIM_SLIDE_IN_RIGHT;
			break;
		default:
			return TVE_Leads_Animation_Abstract::ANIM_INSTANT;
	}
}

/**
 * wrapper over the wp_enqueue_script function
 * it will add the plugin version to the script source if no version is specified
 *
 * @param        $handle
 * @param string $src
 * @param array $deps
 * @param bool $ver
 * @param bool $in_footer
 */
function tve_leads_enqueue_script( $handle, $src = false, $deps = array(), $ver = false, $in_footer = false ) {
	if ( $ver === false ) {
		$ver = TVE_LEADS_VERSION;
	}

	if ( defined( 'TVE_DEBUG' ) && TVE_DEBUG ) {
		$src = str_replace( '/js-min/', '/js/', $src );
		$src = preg_replace( '#\.min\.js$#', '.js', $src );
	}

	wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer );
}

/**
 * wrapper over the wp_enqueue_style function
 * it will add the plugin version to the style link if no version is specified
 *
 * @param             $handle
 * @param string $src
 * @param array $deps
 * @param bool|string $ver
 * @param string $media
 */
function tve_leads_enqueue_style( $handle, $src = false, $deps = array(), $ver = false, $media = 'all' ) {
	if ( $ver === false ) {
		$ver = TVE_LEADS_VERSION;
	}
	wp_enqueue_style( $handle, $src, $deps, $ver, $media );
}


/**
 *
 * gets the nice name for a form type
 *
 * @param WP_Post|int|string $form_type can either be a WP_Post object, a form type ID or a string in the form of 'ribbon' for example
 *
 * @return string the nice post name
 */
function tve_leads_get_form_type_name( $form_type ) {
	if ( is_numeric( $form_type ) || $form_type instanceof WP_Post ) {
		$form_type = get_post_meta( $form_type, 'tve_form_type', true );
	}

	if ( ! is_string( $form_type ) ) {
		return '';
	}

	$all = tve_leads_get_default_form_types( true );

	if ( ! isset( $all[ $form_type ] ) ) {
		return '';
	}

	return $all[ $form_type ]['post_title'];
}

/**
 *
 * get the equivalent test type based on post type of the form
 *
 * @param string $post_type
 *
 * @return string the test_type constant
 */
function tve_leads_get_test_type_from_post_type( $post_type ) {
	return $post_type == TVE_LEADS_POST_FORM_TYPE
		? TVE_LEADS_VARIATION_TEST_TYPE
		:
		( $post_type == TVE_LEADS_POST_SHORTCODE_TYPE
			? TVE_LEADS_SHORTCODE_TEST_TYPE
			: ( $post_type == TVE_LEADS_POST_TWO_STEP_LIGHTBOX ? TVE_LEADS_TWO_STEP_LIGHTBOX_TEST_TYPE : TVE_LEADS_GROUP_TEST_TYPE ) );
}

/**
 * wrapper over the wp get_option function - it appends the tve_leads_ prefix to the option name
 *
 * @param      $name
 * @param bool $default
 *
 * @return mixed
 */
function tve_leads_get_option( $name, $default = false ) {
	$name  = 'tve_leads_' . preg_replace( '/^tve_leads_/', '', $name );
	$value = get_option( $name, $default );
	if ( $name === 'tve_leads_ajax_load' ) {
		$value = (int) $value;
	}

	return $value;
}

/**
 * gets the page data - used to build the the breadcrumbs
 *
 * @return mixed
 */
function tve_leads_get_screen_data() {
	$current_screen = get_current_screen();
	if ( strpos( $current_screen->base, 'toplevel_page_' ) !== false ) {
		$url = '#dashboard';
	} else {
		$path = str_replace( 'thrive-leads_page_', '', $current_screen->base );
		$url  = menu_page_url( $path, false );
	}

	$screen_data[0]['name'] = 'Thrive Dashboard';
	$screen_data[0]['url']  = menu_page_url( 'tve_dash_section', false );
	$screen_data[1]['name'] = 'Thrive Leads';
	$screen_data[1]['url']  = menu_page_url( 'thrive_leads_dashboard', false );
	$screen_data[2]['name'] = str_replace( 'Thrive Leads ', '', get_admin_page_title() );
	$screen_data[2]['url']  = $url;
	$screen_data[2]['last'] = 1;

	return $screen_data;
}

/**
 * wrapper over the wp update_option() function
 * it ensures the option is prefixed with "tve_leads_" prefix
 *
 * @param string $name
 * @param mixed $value
 *
 * @return bool
 */
function tve_leads_update_option( $name, $value ) {
	$name = 'tve_leads_' . preg_replace( '/^tve_leads_/', '', $name );

	return update_option( $name, $value );
}

/**
 * get all form types that are to be shown on a page based on the $lead_group
 *
 * @param WP_Post $lead_group
 * @param bool $skip_group_tests whether or not to take into account any tests that are running at group level
 *
 * @return array
 */
function tve_leads_get_targeted_form_types( $lead_group, $skip_group_tests = false ) {
	$form_types_to_be_shown = array();

	$group_level_tests = $skip_group_tests ? array() : tve_leads_get_group_active_tests( $lead_group->ID );

	/* gather first all the available form types */
	foreach ( $lead_group->form_types as $form_type ) {
		if ( is_array( $form_type ) || ! $form_type->ID ) {
			continue;
		}
		$display_on_mobile = get_post_meta( $form_type->ID, 'display_on_mobile', true );
		$display_on_mobile = (string) $display_on_mobile === '' ? 1 : (int) $display_on_mobile;
		if ( $display_on_mobile === 0 && wp_is_mobile() ) {
			continue;
		}

		$display_status = get_post_meta( $form_type->ID, 'display_status', true );
		$display_status = (string) $display_status === '' ? 1 : (int) $display_status;
		/* since 05.09.2016 display status is display on desktop so we just check if this is not a mobile */
		if ( $display_status === 0 && ! wp_is_mobile() ) {
			continue;
		}
		/**
		 * eliminate screenfillers, lightboxes, ribbons and slideins from the customize preview screens
		 */
		if ( tve_leads_is_customize_preview() && in_array( $form_type->tve_form_type, array(
				'lightbox',
				'screen_filler',
				'ribbon',
				'slide_in'
			) ) ) {
			continue;
		}
		$form_types_to_be_shown[ $form_type->ID ] = $form_type;
	}
	/* bail early if no form type has been found */
	if ( empty( $form_types_to_be_shown ) ) {
		return array();
	}

	if ( empty( $group_level_tests ) ) {
		/* we need to show all form types, so there's nothing to be done here */

	} else {
		/* take every form_type that's not included in a test and ALL OTHER form types */
		foreach ( $group_level_tests as $test ) {

			$visited_form = tve_leads_get_visited_test_form( $lead_group->ID, $test->item_ids );

			/* if we previously visited one of the form types, we display the same one and not get a random index */
			$random_index = empty( $visited_form ) ? tve_leads_get_random_index( count( $test->item_ids ) ) : array_search( $visited_form, $test->item_ids );

			foreach ( $test->item_ids as $index => $_id ) {
				/* remove all other form types that are included in the test and have a different index in the test_items array */
				if ( $random_index != $index ) {
					unset( $form_types_to_be_shown[ $_id ] );
					continue;
				}
				if ( ! isset( $form_types_to_be_shown[ $_id ] ) ) {
					continue;
				}
				$form_types_to_be_shown[ $_id ]->group_level_test = $test;
			}
		}
	}

	return $form_types_to_be_shown;
}

/**
 * For a test at a group level, check in the cookies if we already saw one of the form types.
 * If we already have a unique impression for a form, we return the form id
 *
 * @param $lead_group_id
 * @param $test_items_ids
 *
 * @return int
 */
function tve_leads_get_visited_test_form( $lead_group_id, $test_items_ids ) {
	$cookies = array_keys( $_COOKIE );

	foreach ( $cookies as $cookie ) {
		/* search for cookies from our lead group */
		if ( strpos( $cookie, 'tl_' . $lead_group_id ) === 0 ) {
			/* cookie -> tl_{group_id}_{form_id}_{variation_id} */
			$parts = explode( '_', $cookie );

			if ( count( $parts ) !== 4 ) {
				/* make sure we have the right cookie */
				break;
			}

			$form_type_id = $parts[2];

			if ( in_array( $form_type_id, $test_items_ids ) ) {
				return (int) $form_type_id;
			}
		}
	}

	return 0;
}

/**
 * output inline setcookies using inline <script>s
 *
 * @param array $cookies
 *
 * @return string the inline javascript
 */
function tve_leads_inline_cookies( $cookies ) {
	if ( empty( $cookies ) ) {
		return '';
	}
	$output = '<script type="text/javascript">var _now = new Date(), sExpires;';
	foreach ( $cookies as $key => $cookie ) {
		$output .= '_now.setTime(_now.getTime() + (' . intval( $cookie['expires'] ) . ' * 24 * 3600 * 1000));sExpires = _now.toUTCString();';
		$output .= 'document.cookie=encodeURIComponent(' . json_encode( $key ) . ")+'='+encodeURIComponent(" . json_encode( $cookie['value'] ) . ")+';expires='+sExpires+';path=/';";
	}
	$output .= '</script>';

	return $output;
}

/**
 * output the JS code required for a trigger associated with a variation
 *
 * @param array $variation
 * @param string $form_id
 * @param string $form_type
 */
function tve_leads_output_trigger_js( $variation, $form_id, $form_type ) {
	$trigger = TVE_Leads_Trigger_Abstract::factory( $variation['trigger'], $variation['trigger_config'] );
	if ( is_null( $trigger ) ) {
		return;
	}
	$trigger->output_js( array(
		'form_id'   => 'tve-leads-track-' . $form_id,
		'form_type' => $form_type,
	) );
}

/**
 * determine which form variation to display from a $form_type
 * takes into account also the (possible) running tests between variations from the form type
 *
 * if a test is running and the user has visited the page before, we need to show him the same form
 * we do this by dropping a cookie with the generated variation index from the ones included in the test
 *
 * also, if we detect a mobile browser (using wp_is_mobile) and the user did not setup the form to be displayed on mobile, then the result will be empty
 *
 * for some forms, there is a display_frequency setting which prevents the form for displaying for a set amount of time (days)
 * this is also solved with a cookie, and also handled here
 *
 * @param WP_Post $form_type
 * @param bool $skip_cookie_check whether or not to skip the cookie check in case of an active test running
 *
 * @return array|null the form variation or empty for failure
 */
function tve_leads_determine_variation( $form_type, $skip_cookie_check = false ) {
	$_type      = $form_type->tve_form_type;
	$test_model = ! empty( $form_type->group_level_test ) ? $form_type->group_level_test : false;
	/**
	 * IF there is no active test at group level -> take into account tests at form type level
	 *
	 * If there is a test running at variation level, only get active test items for that test
	 */
	if ( empty( $test_model ) ) {
		$variation_active_test = tve_leads_get_form_active_test( $form_type->ID, array(
			'test_type' => null,
			'get_items' => false
		) );
	}

	$variations = tve_leads_get_form_variations( $form_type->ID, array(
		'tracking_data'      => false,
		'post_status'        => TVE_LEADS_STATUS_PUBLISH,
		'active_for_test_id' => ! empty( $variation_active_test ) && ! empty( $variation_active_test->id ) ? $variation_active_test->id : false,
	) );

	/* no active variation, nothing to do here */
	if ( empty( $variations ) ) {
		return array();
	}

	$cookies_to_set = array();
	/* if there's a test running at form type level and no test at group level -> choose a random form variation */
	if ( empty( $test_model ) && ! empty( $variation_active_test ) ) {
		$test_model = $variation_active_test;

		if ( ! $skip_cookie_check ) {
			/**
			 * if there's a previous cookie key setup for this variation and a test is running, then we should show the same variation to the user
			 */
			$same_variation_key = 't_' . $test_model->id . '_f_' . $form_type->ID;
			if ( isset( $_COOKIE[ $same_variation_key ] ) && isset( $variations[ $_COOKIE[ $same_variation_key ] ] ) ) {
				$variation_index = $_COOKIE[ $same_variation_key ];
			} else {
				$variation_index = tve_leads_get_random_index( count( $variations ) );
			}
			if ( ! headers_sent() ) {
				setcookie( $same_variation_key, $variation_index, time() + 3600 * 30, '/' );
			} else {
				$cookies_to_set[ $same_variation_key ] = array(
					'value'   => $variation_index,
					'expires' => 30,
				);
			}
		} else {
			$variation_index = tve_leads_get_random_index( count( $variations ) );
		}
	} else {
		/* else always choose the first published variation = the control */
		$variation_index = 0;
	}

	//just in case it does not find that index of variation
	$variation = isset( $variations[ $variation_index ] ) ? $variations[ $variation_index ] : $variations[0];
	/* some sanity checks - check if we have content / templates for the variation */
	if ( empty( $variation[ TVE_LEADS_FIELD_TEMPLATE ] ) ) {
		return array();
	}

	/**
	 * if the user has setup a display frequency (in days) for this particular form, we need to check if this form has been displayed
	 * in the past x days on this browser. We do this by checking the value of a cookie.
	 */
	if ( $variation['display_frequency'] && tve_leads_form_type_has_frequency_settings( $_type ) ) {

		$cookie_key = 'tlf_' . $variation['key'];
		/**
		 * if the cookie is set, then there's nothing more to do here
		 */
		if ( isset( $_COOKIE[ $cookie_key ] ) ) {
			unset( $GLOBALS['tve_lead_forms'][ $_type ] );

			return array();
		}

		/**
		 * otherwise, set the cookie to expire after the number of days setup for the form
		 */
		if ( ! headers_sent() ) {
			setcookie( $cookie_key, 1, time() + ( 3600 * 24 * (int) $variation['display_frequency'] ), '/' );
		} else {
			$cookies_to_set[ $cookie_key ] = array(
				'value'   => 1,
				'expires' => (int) $variation['display_frequency'],
			);
		}
	}

	$variation['test_model']  = $test_model;
	$variation['set_cookies'] = $cookies_to_set;

	return $variation;
}

/**
 * set a cookie (flag) that marks just that a user converted a form from $main_group_id
 * another cookie is set containing also the email address, that's a separate one, and allows us to track multiple conversions from the same browser
 * (if the emails are different)
 *
 * @param int $main_group_id the id for the main group
 */
function tve_leads_set_conversion_cookie( $main_group_id ) {
	setcookie( 'tl_conversion_' . $main_group_id, '1', time() + ( 365 * 24 * 3600 ), '/' );
}

/**
 * Check if a user has converted on a form from a lead group / shortcode / 2-step
 *
 * @param int $main_group_id the id for the main group
 *
 * @return bool
 */
function tve_leads_check_conversion_cookie( $main_group_id ) {
	return isset( $_COOKIE[ 'tl_conversion_' . $main_group_id ] );
}

/**
 * check if we are previewing a TL form
 */
function tve_leads_is_preview_page() {
	$post_type = get_post_type( get_the_ID() );
	if ( ! in_array( $post_type, array(
		TVE_LEADS_POST_FORM_TYPE,
		TVE_LEADS_POST_TWO_STEP_LIGHTBOX,
		TVE_LEADS_POST_SHORTCODE_TYPE
	) ) ) {
		return false;
	}

	global $variation;
	if ( empty( $variation ) ) {
		return false;
	}

	return true;
}

/**
 * check if we are editing a TL form
 */
function tve_leads_is_editor_page() {
	$post_type = get_post_type( get_the_ID() );
	if ( ! in_array( $post_type, array(
		TVE_LEADS_POST_FORM_TYPE,
		TVE_LEADS_POST_TWO_STEP_LIGHTBOX,
		TVE_LEADS_POST_SHORTCODE_TYPE
	) ) ) {
		return false;
	}

	global $variation;
	if ( empty( $variation ) ) {
		return false;
	}

	return isset( $_GET[ TVE_EDITOR_FLAG ] );
}

/**
 * check if a conversion has been registered for this variation and, if so, we need to check if there is an "Already subscribed" state defined and show that instead
 *
 * @param array $variation the main variation where the "Already Subscribed" state should have been setup
 * @param string $type type of form
 * @param bool $skip_inbound_link_check whether or not to skip the check for 'already_subscribed' state from the inbound link params
 * @param bool $for_shortcode whether the current call is done for a shortcode. if true and $skip_inbound_link_check is false, it checks that the "subscribed" state is checked for inbound links and all forms are targeted
 *
 * @return string
 */
function tve_leads_get_already_subscribed_html( $variation, $type, $skip_inbound_link_check = false, $for_shortcode = false ) {
	$show_already_subscribed = $skip_inbound_link_check ? false : tve_leads_force_subscribed_state( $for_shortcode );

	if ( empty( $variation ) || ! empty( $variation['parent_id'] ) || ( ! isset( $_COOKIE[ 'tl-conv-' . $variation['key'] ] ) && ! $show_already_subscribed ) ) {
		return '';
	}

	$done = tve_leads_get_already_subscribed_state( $variation );

	if ( empty( $done ) ) {
		return '';
	}

	/* Return empty when the content is hidden */
	if ( tve_leads_check_variation_visibility( $done ) ) {
		return TVE_ALREADY_SUBSCRIBED_HIDDEN;
	}

	/**
	 * enqueue the scripts / styles for the already subscribed state
	 */
	tve_leads_enqueue_variation_scripts( $done );

	$ajax_load_forms = tve_leads_get_option( 'ajax_load' );
	if ( $ajax_load_forms && wp_doing_ajax() ) {
		$GLOBALS['tve_leads_subscribed_states']   = isset( $GLOBALS['tve_leads_subscribed_states'] ) ? $GLOBALS['tve_leads_subscribed_states'] : array();
		$GLOBALS['tve_leads_subscribed_states'][] = $done;
		remove_filter( 'tve_leads_append_states_ajax', 'tve_leads_ajax_already_subscribed_state' );
		add_filter( 'tve_leads_append_states_ajax', 'tve_leads_ajax_already_subscribed_state' );
	}

	$fn = 'tve_leads_display_form_' . $type;

	return $fn( '__return_content', tve_editor_custom_content( $done ), $done, array(
		'wrap' => false,
	) );
}

/**
 * append any possible already_subscribed state to the list of variations that are to be processed and returned when lazy-loading is enabled
 *
 * @param array $output_variations
 *
 * @return array
 */
function tve_leads_ajax_already_subscribed_state( $output_variations ) {
	if ( empty( $GLOBALS['tve_leads_subscribed_states'] ) ) {
		return $output_variations;
	}

	if ( empty( $output_variations ) || ! is_array( $output_variations ) ) {
		$output_variations = array();
	}

	$output_variations = array_merge( $output_variations, $GLOBALS['tve_leads_subscribed_states'] );

	return $output_variations;
}

/**
 * return the html for a variation state
 * used in all form types except for lightboxes
 *
 * @param string $form_html
 * @param array $variation
 * @param array $control used to control pieces of html
 *
 * @return string
 */
function tve_leads_state_html( $form_html, $variation, $control ) {
	return sprintf(
		'<div%s class="tl-style" id="%s" data-state="%s" data-form-state="%s">%s</div>',
		! empty( $control['hide'] ) ? ' style="display:none"' : '',
		'tve_' . tve_leads_get_variation_style_key( $variation ),
		$variation['key'],
		$variation['form_state'],
		$form_html
	);
}

/**
 *
 * gets the CSS style key needed for a variation, based on the template
 *
 * @param array $variation
 *
 * @return string the style key
 */
function tve_leads_get_variation_style_key( &$variation ) {
	if ( ! isset( $variation['style_key'] ) ) {
		$parts                  = explode( '|', $variation[ TVE_LEADS_FIELD_TEMPLATE ] );
		$key                    = end( $parts );
		$variation['style_key'] = preg_replace( '#_v(.+)$#', '', $key );;
	}

	return $variation['style_key'];
}

/**
 * WP wrapper / shim over the WP is_customize_preview function (if available)
 *
 * @return bool
 */
function tve_leads_is_customize_preview() {
	if ( function_exists( 'is_customize_preview' ) ) {
		return is_customize_preview();
	}

	global $wp_customize;

	return is_a( $wp_customize, 'WP_Customize_Manager' ) && $wp_customize->is_preview();
}

/**
 * main entry-point for displaying a PHP_INSERT form type
 * users are able to use this php code to insert a form anywhere in the site
 *
 * @param string $main_group_id
 * @param string $form_type_or_shortcode_id
 */
function tve_leads_form_display( $main_group_id = null, $form_type_or_shortcode_id = null ) {
	if ( empty( $main_group_id ) && empty( $form_type_or_shortcode_id ) ) {
		echo __( 'There is a problem with this PHP insert: missing both parameters', 'thrive-leads' );

		return;
	}

	/**
	 * if ths form is a PHP insert and the main group is not targeted, bail early
	 */
	if ( ! empty( $main_group_id ) ) {
		global $tve_lead_group;
		if ( empty( $tve_lead_group ) || $tve_lead_group->ID != $main_group_id ) {
			return;
		}
	}

	$form_type = tve_leads_get_form_type( $form_type_or_shortcode_id, array( 'get_variations' => false ) );

	switch ( $form_type->tve_form_type ) {
		case 'shortcode':
			echo tve_leads_shortcode_render( array( 'id' => $form_type_or_shortcode_id ) );
			break;
		case 'php_insert':
			if ( empty( $GLOBALS['tve_lead_forms']['php_insert'] ) ) {
				return;
			}
			echo tve_leads_display_form_php_insert();
			break;
	}

}

/**
 * Checks to see if the current screen represents a page, post, blog, index, front and so on.
 * Returns an array with the ID and type.
 *
 * @return array
 */
function tve_get_current_screen() {
	$id = get_the_ID();
	if ( is_front_page() ) {
		$data = array(
			'screen_type' => TVE_SCREEN_HOMEPAGE,
			'screen_id'   => 0,
		);
	} elseif ( is_home() ) {
		$data = array(
			'screen_type' => TVE_SCREEN_BLOG,
			'screen_id'   => 0,
		);
	} elseif ( is_singular() ) {
		switch ( get_post_type( $id ) ) {
			case 'post':
				$type = TVE_SCREEN_POST;
				break;
			case 'page':
				$type = TVE_SCREEN_PAGE;
				break;
			default:
				$type = TVE_SCREEN_CUSTOM_POST;
		}
		$data = array(
			'screen_type' => $type,
			'screen_id'   => $id,
		);
	} elseif ( is_archive() ) {
		$data = array(
			'screen_type' => TVE_SCREEN_ARCHIVE,
			'screen_id'   => 0,
		);
	} else {
		$data = array(
			'screen_type' => TVE_SCREEN_OTHER,
			'screen_id'   => 0,
		);
	}

	return $data;
}


/**
 * Returns readable information for reporting table of the screen from where the log was made
 *
 * @param $screen_type
 * @param $screen_id
 *
 * @return array Array with url, type and name of the page
 * @see tve_get_current_screen()
 *
 */
function tve_get_current_screen_for_reporting_table( $screen_type, $screen_id ) {
	global $wp_rewrite;
	$wp_rewrite = new WP_Rewrite();
	switch ( $screen_type ) {
		case TVE_SCREEN_HOMEPAGE:
			return array(
				get_home_url(),
				__( 'Homepage', 'thrive-leads' ),
				__( 'Homepage', 'thrive-leads' ),
			);
			break;
		case TVE_SCREEN_BLOG:
			return array(
				get_permalink( get_option( 'page_for_posts' ) ),
				__( 'Blog', 'thrive-leads' ),
				__( 'Blog', 'thrive-leads' ),
			);
			break;
		case TVE_SCREEN_POST:
		case TVE_SCREEN_PAGE:
		case TVE_SCREEN_CUSTOM_POST:
			return array(
				get_permalink( $screen_id ),
				get_post_type( $screen_id ) ? get_post_type( $screen_id ) : '',
				get_the_title( $screen_id ),
			);
			break;
		case TVE_SCREEN_ARCHIVE:
			return array(
				'',
				__( 'Archive', 'thrive-leads' ),
				__( 'Archive', 'thrive-leads' ),
			);
			break;
		case TVE_SCREEN_OTHER:
			return array(
				'',
				__( 'Other', 'thrive-leads' ),
				__( 'Other', 'thrive-leads' ),
			);
			break;
		default:
			return array(
				'',
				__( 'Unknown', 'thrive-leads' ),
				__( 'Unknown', 'thrive-leads' ),
			);
	}
}

/**
 * Resolve a TVE_SCREEN_* constant to a human-readable string.
 *
 * @param int $screen_type One of the TVE_SCREEN_* constants.
 *
 * @return string Lowercase screen type label (e.g. 'page', 'post', 'homepage').
 */
function tve_leads_get_screen_type_label( $screen_type ) {
	$map = array(
		TVE_SCREEN_HOMEPAGE    => 'homepage',
		TVE_SCREEN_BLOG        => 'blog',
		TVE_SCREEN_PAGE        => 'page',
		TVE_SCREEN_POST        => 'post',
		TVE_SCREEN_CUSTOM_POST => 'custom_post',
		TVE_SCREEN_ARCHIVE     => 'archive',
		TVE_SCREEN_OTHER       => 'other',
	);

	return isset( $map[ $screen_type ] ) ? $map[ $screen_type ] : 'unknown';
}

/**
 * Return an array with all the fields that we want to ignore when storing contacts in the database.
 * Email is already stored in another variable so we don't need it again
 *
 * @return array
 */
function tve_get_lead_generation_ignored_fields() {
	return array(
		'email',
		'_captcha_size',
		'_captcha_theme',
		'_captcha_type',
		'_submit_option',
		'_use_captcha',
		'g-recaptcha-response',
		'__tcb_lg_fc',
		'__tcb_lg_msg',
		'_state',
		'_form_type',
		'_error_message_option',
		'_back_url',
		'_submit_option',
		'url',
		'_asset_group',
		'_asset_option',
		'mailchimp_optin',
		'tcb_token',
		'tve_labels',
		'tve_mapping',
		'_api_custom_fields',
		'_sendParams',
		'_autofill',
	);
}

/**
 * check if there is a cookie set that forces the "Already Subscribed" state to be displayed.
 * this can only come from the inbound link functionality
 *
 * @param bool $for_shortcode whether or not this current form is a shortcode. If true, it ignores the lead group and checks if: All forms are targeted with inbound links and the option is "show already subscribed state"
 *
 * @return bool
 */
function tve_leads_force_subscribed_state( $for_shortcode = false ) {
	if ( $for_shortcode ) {
		return ! empty( $_COOKIE['tl_inbound_target_all'] );
	}
	global $tve_lead_group;
	if ( empty( $tve_lead_group ) ) {
		return false;
	}
	$group_cookie_name = 'tl_inbound_link_params_' . $tve_lead_group->ID;

	$show_already_subscribed = false;
	if ( isset( $_COOKIE[ $group_cookie_name ] ) ) {
		$inbound_link_params     = thrive_safe_unserialize( stripslashes( $_COOKIE[ $group_cookie_name ] ) );
		$show_already_subscribed = ! empty( $inbound_link_params['tl_form_type'] );
	}

	return $show_already_subscribed;
}

/**
 * Check if the current state of the variation is visible
 *
 * @param array $variation
 *
 * @return bool
 */
function tve_leads_check_variation_visibility( $variation = array() ) {
	return isset( $variation[ TVE_LEADS_FIELD_STATE_VISIBILITY ] ) && empty( $variation[ TVE_LEADS_FIELD_STATE_VISIBILITY ] );
}

/**
 * get a reliable timezone string, even if it's set to a manual time difference (UTC+/-)
 *
 * @return string
 */
function tve_get_timezone_string() {
	// if site timezone string exists, return it
	if ( $timezone = get_option( 'timezone_string' ) ) {
		return $timezone;
	}

	// get UTC offset, if it isn't set then return UTC
	if ( 0 === ( $utc_offset = get_option( 'gmt_offset', 0 ) ) ) {
		return 'UTC';
	}

	// adjust UTC offset from hours to seconds
	$utc_offset *= 3600;

	// attempt to guess the timezone string from the UTC offset
	if ( $timezone = timezone_name_from_abbr( '', $utc_offset, 0 ) ) {
		return $timezone;
	}

	// last try, guess timezone string manually
	$is_dst = date( 'I' );

	foreach ( timezone_abbreviations_list() as $abbr ) {
		foreach ( $abbr as $city ) {
			if ( $city['dst'] == $is_dst && $city['offset'] == $utc_offset ) {
				return $city['timezone_id'];
			}
		}
	}

	// fallback to UTC
	return 'UTC';
}

/**
 * get a list of all templates downloaded from the cloud based on form type
 *
 * @param string $form_type
 *
 * @return array
 */
function tve_leads_get_downloaded_templates( $form_type ) {
	return get_option( 'tve_leads_' . $form_type . '_downloaded_templates', array() );
}

/**
 * save the list of downloaded templates into the wp_option used for these
 *
 * @param string $form_type
 * @param array $templates
 */
function tve_leads_save_downloaded_templates( $form_type, $templates ) {
	update_option( 'tve_leads_' . $form_type . '_downloaded_templates', $templates );
}

function tve_leads_is_cloud_template( $form_type, $template ) {

	if ( strpos( $template, '|' ) !== false ) {
		$template = substr( $template, strpos( $template, '|' ) + 1 );
	}

	$cloud = tve_leads_get_downloaded_templates( $form_type );

	return ! empty( $cloud[ $template ] );
}

/**
 * Displays notices of inconclusive tests
 *
 * @param $id
 */
function tve_inconclusive_tests_notice() {
	$running_tests = tve_get_running_inconclusive_tests();

	$inconclusive_tests_option = get_option( 'tve_inconclusive_tests' );
	$inconclusive_tests        = array();
	if ( ! is_array( $inconclusive_tests_option ) ) {
		$inconclusive_tests = explode( ',', get_option( 'tve_inconclusive_tests' ) );
	}
	foreach ( $running_tests as $tests ) {
		$id = $tests->id;

		if ( ! in_array( $id, $inconclusive_tests ) ) {
			?>
            <div data-test-id="<?php echo $id; ?>"
                 class="notice-error notice tve_error_inconclusive_test_notice is-dismissible">
                <p><?php echo __( 'One of your active A/B tests in Thrive Leads appears to be inconclusive. The test has reached double the threshold time and conversion numbers, but no clear winner has been found. <a href="javascript:void(0);" onclick="ThriveLeadsInconclusive.inconclusive_tests.trigger_dismiss_notice(' . $id . ')">Click here to view the test</a>.', 'thrive-leads' ); ?></p>
            </div>
			<?php
		}
	}
}

/**
 * returns an array of error messages for default templates
 *
 * @return array
 */
function tve_leads_errors_config() {
	return array(
		'email'            => 'Please enter a valid email address',
		'phone'            => 'Please enter a valid phone number',
		'required'         => 'Name and Email fields are required',
		'password'         => 'Please enter a password',
		'passwordmismatch' => 'The passwords do not match',
	);
}

/**
 * Create a new editor instance so we can use it on the asset delivery system
 */
function tve_leads_output_wysiwyg_editor() {
	$screen = get_current_screen();

	if ( $screen->id !== 'admin_page_thrive_leads_asset_delivery' ) {
		return;
	}

	echo '<div id="tve-leads-asset-editor-wrapper" style="display: none">';
	wp_editor( '', 'default-editor', array(
		'dfw'               => true,
		'tabfocus_elements' => 'insert-media-button,save-post',
		'editor_height'     => 360,
		'textarea_rows'     => 15,
	) );
	echo '</div>';
}

function tve_leads_template( $file, $data = null, $return = false ) {
	if ( strpos( $file, '.php' ) === false ) {
		$file .= '.php';
	}

	$file      = ltrim( $file, '\\/' );
	$file_path = TVE_LEADS_PATH . 'inc/views/' . $file;
	$content   = null;

	if ( ! is_file( $file_path ) ) {
		return false;
	}

	if ( false !== $return ) {
		ob_start();
		include $file_path;
		$content = ob_get_contents();
		ob_end_clean();
	} else {
		include $file_path;
	}

	return $content;
}

/**
 * Gets a list of templates from Cloud to be usually shown on Templates Lightbox
 *
 * @param $form_type      string
 * @param $get_multi_step bool
 *
 * @return array
 */
function tve_leads_get_cloud_templates( $form_type, $get_multi_step ) {

	$transient_name = 'tve_leads_' . $form_type . '_template_cloud';

	if ( defined( 'TL_CLOUD_DEBUG' ) && TL_CLOUD_DEBUG ) {
		delete_transient( $transient_name );
	}

	if ( false === ( $templates = get_transient( $transient_name ) ) ) {

		try {

			$templates = Thrive_Leads_Cloud_Templates_APi::getInstance()->init( array( 'form_type' => $form_type ) )->getTemplateList( ! (bool) $get_multi_step );
			set_transient( $transient_name, $templates, 8 * HOUR_IN_SECONDS );

		} catch ( Exception $e ) {

			$templates = array();
		}

	}
	if ( empty( $templates['error'] ) ) {
		foreach ( $templates as &$tpl ) {
			$tpl['key']       = ( $tpl['multi_step'] ? 'multi_step|' : '' ) . $form_type . '|' . $tpl['key'];
			$tpl['form_type'] = $form_type;
			$tpl['cloud']     = true;
		}
	}

	return $templates;
}

/**
 * Check if a TL template is a cloud template or a local template
 *
 * @param string $template_key
 *
 * @return bool
 */
function tve_leads_is_v2_template( $template_key ) {

	return strpos( $template_key, 'tcb2_' ) === 0;
}

/**
 *
 * Get the default CSS for a TL template - only applicable for v2 templates
 * The CSS can either be stored locally, for the blank template, or downloaded from the cloud, stored in a file in the wp-uploads folder
 *
 * @param string $template_key
 * @param array $template_config
 *
 * @return string
 */
function tve_leads_get_default_template_css( $template_key, $template_config = array() ) {

	$head_css = '';
	list( $form_type, $template ) = explode( '|', $template_key );

	if ( tve_leads_is_v2_template( $template ) ) {
		if ( tve_leads_is_cloud_template( $form_type, $template ) ) {
			$css_file = tve_leads_get_cloud_folder_path( $form_type, $template ) . 'css/style.css';
			if ( file_exists( $css_file ) ) {
				$head_css = file_get_contents( $css_file );
				$head_css = str_replace( '{tve_leads_base_url}', tve_leads_get_cloud_folder_url( $form_type, $template ) . 'images/', $head_css );
			}
		} else {
			/**
			 * at this point, this is a default v2 template ( blank set v2 )
			 */
			$css_file = plugin_dir_path( dirname( __FILE__ ) ) . 'editor-templates/_tcb2_css/' . $form_type . '_' . $template . '.css';
			if ( file_exists( $css_file ) ) {
				$head_css = file_get_contents( $css_file );
			}
		}
	}

	return $head_css;
}

/**
 * Check if Setup of Asset Delivery is completed/valid
 *
 * @return bool
 */
function tve_leads_asset_delivery_setup_valid() {

	$connection     = get_option( 'tve_api_delivery_service', false );
	$email_body     = get_option( 'tve_leads_asset_mail_subject', false );
	$email_subject  = get_option( 'tve_leads_asset_mail_body', false );
	$connected_apis = Thrive_List_Manager::get_available_apis( true, [ 'include_types' => [ 'email' ] ] );

	return ! empty( $connection ) && ! empty( $email_body ) && ! empty( $email_subject ) && ! empty( $connected_apis );
}

/**
 *
 * Get the full path to the folder storing downloaded TL cloud templates
 *
 * @param string $form_type
 * @param string $template
 *
 * @return string
 */
function tve_leads_get_cloud_folder_path( $form_type = null, $template = null ) {
	$upload = wp_upload_dir();
	if ( ! empty( $upload['error'] ) ) {
		return '';
	}

	return trailingslashit( $upload['basedir'] ) . TVE_LEADS_CLOUD_FORM_FOLDER . '/' . ( $form_type ? $form_type . '/' : '' ) . ( $template ? $template . '/' : '' );
}

/**
 *
 * Get the full URL to the folder storing downloaded TL cloud templates
 *
 * @param string $form_type
 * @param string $template
 *
 * @return string
 */
function tve_leads_get_cloud_folder_url( $form_type = null, $template = null ) {
	$upload = wp_upload_dir();
	if ( ! empty( $upload['error'] ) ) {
		return '';
	}

	$base_url = str_replace( array( 'http://', 'https://' ), '//', $upload['baseurl'] );

	return trailingslashit( $base_url ) . TVE_LEADS_CLOUD_FORM_FOLDER . '/' . ( $form_type ? $form_type . '/' : '' ) . ( $template ? $template . '/' : '' );
}

/**
 * Get the default configuration for the new TCB2 blank template
 *
 * @return array
 */
function tve_leads_get_v2_blank_config( $form_type ) {

	return array(
		'key'  => $form_type . '|tcb2_blank',
		'name' => 'Blank Template',
		'meta' => array(
			TVE_LEADS_FIELD_USER_CSS => '.tve-leads-conversion-object .thrv_heading h1,.tve-leads-conversion-object .thrv_heading h2,.tve-leads-conversion-object .thrv_heading h3{margin:0;padding:0}.tve-leads-conversion-object .thrv_text_element p,.tve-leads-conversion-object .thrv_text_element h1,.tve-leads-conversion-object .thrv_text_element h2,.tve-leads-conversion-object .thrv_text_element h3{margin:0}',
		),
	);
}

/**
 *
 * Process the Custom CSS rules to be added to the page
 * SUPP-3939 - make sure the rules are only applied to TL forms, and not everywhere
 *
 * @param string $css
 */
function tve_leads_process_custom_css( $css ) {
	$css = preg_replace( '#^\.thrv_heading h1#', '.tve-leads-conversion-object .thrv_heading h1', $css );
	$css = str_replace( array( ',.thrv_heading', ',.thrv_text_element' ), array(
		',.tve-leads-conversion-object .thrv_heading',
		',.tve-leads-conversion-object .thrv_text_element',
	), $css );

	return $css;
}

/**
 * Format a date using a specific format, or the one setup from general settings
 *
 * @param string $date_string the date
 * @param null|string $format format. if not passed, it will take the default WordPress settings
 *
 * @return string the formatted date
 */
function tve_leads_format_date( $date_string, $format = null ) {
	if ( ! $format ) {
		$format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' );
		if ( ! trim( $format ) ) {
			$format = 'd M, Y G:i'; // a default format
		}
	}

	return mysql2date( $format, $date_string );
}

/**
 * Prepare placeholder for ajax displayed forms
 *
 * @param      $type
 * @param null $control_variation
 *
 * @return string
 */
function tve_leads_get_form_placeholder( $type, $control_variation = null ) {

	$o_type = $type;
	if ( $type === 'before_widget' ) {
		$type = 'widget';
	}
	if ( empty( $GLOBALS['tve_lead_forms'][ $type ]['form_type'] ) && $control_variation === null ) {
		$placeholder = sprintf( '<span style="display:none" class="tl-placeholder-f-type-%s"></span>', $type );
	} else {
		$form_class = "tl-placeholder-f-type-$type";

		if ( $control_variation === null ) {
			foreach ( $GLOBALS['tve_lead_forms'][ $type ]['form_type']->variations as $variation ) {
				if ( $variation['is_control'] ) {
					/* read form heights from the control in case we run a test */
					$control_variation = $variation;
				}
			}
		}

		$placeholder_content = '';

		if (
			! empty( $control_variation['tcb_fields'][ TVE_LEADS_FIELD_FORM_HEIGHT ] ) &&
			( isset( $control_variation['trigger'] ) && in_array( $control_variation['trigger'], array(
					'page_load',
					'viewport'
				) ) ) &&
			! is_editor_page_raw() && /* don't show placeholder inside editor */
			( $type === 'post_footer' || $type === 'widget' || strpos( $type, 'shortcode_' ) === 0 )
		) {
			$form_style = '';

			foreach ( $control_variation['tcb_fields']['form-height'] as $device => $height ) {
				$form_style .= "--tl-form-height-{$device}:{$height}px;";
			}
			$form_class .= ' tl-preload-form';
			/* skeleton placeholder boxes */
			$placeholder_content = '<span></span>';
		} else {
			$form_style = 'display:none';
		}

		switch ( $o_type ) {
			case 'before_widget':
				$placeholder = sprintf( '<div style="%s" class="tl-widget-container %s">%s', $form_style, $form_class, $placeholder_content );
				break;

			default:
				$placeholder = sprintf( '<span style="%s" class="%s">%s</span>', $form_style, $form_class, $placeholder_content );
		}
	}

	return $placeholder;
}

/**
 * Get a generated thumbnail
 *
 * @param $design_id
 *
 * @return string|null
 */
function tl_get_design_thumbnail( $design_id ) {
	$url           = null;
	$wp_upload_dir = wp_get_upload_dir();
	$filename      = $design_id . '.png';
	$filename      = sanitize_file_name( $filename );
	$file_path     = $wp_upload_dir['basedir'] . '/thrive-leads/thumbnails/' . $filename;

	if ( is_file( $file_path ) ) {
		$url = $wp_upload_dir['baseurl'] . '/thrive-leads/thumbnails/' . $filename;
	}

	return $url;
}

/**
 * Get forms that have active variation tests running
 * This is used by the sample data generator plugin for creating sample data for testing charts.
 * 
 * @return array Array of forms with test information
 */
function tve_leads_get_forms_with_active_tests() {
	global $tvedb;
	
	$forms_with_tests = array();
	
	// Get all active tests
	$active_tests = $tvedb->tve_leads_get_tests( array(
		'status' => 'running'
	) );
	
	if ( empty( $active_tests ) ) {
		return $forms_with_tests;
	}
	
	foreach ( $active_tests as $test ) {
		// Get test items for this test
		$test_id = absint( $test->id );
		$test_items = $tvedb->get_test_items( array(
			'test_id' => $test_id
		) );
		
		if ( empty( $test_items ) ) {
			continue;
		}
		
		// Process based on test type
		switch ( $test->test_type ) {
			case TVE_LEADS_VARIATION_TEST_TYPE:
				// Form variation test - get the form type
				foreach ( $test_items as $item ) {
					$form_type_id = absint( $item->form_type_id );
					if ( ! empty( $form_type_id ) ) {
						$form = get_post( $form_type_id );
						if ( $form && $form->post_status === 'publish' ) {
							$forms_with_tests[ absint( $form->ID ) ] = array(
								'form' => $form,
								'test' => $test,
								'test_type' => esc_html__( 'Variation Test', 'thrive-leads' ),
								'parent_group' => get_post( absint( $form->post_parent ) )
							);
						}
					}
				}
				break;
				
			case TVE_LEADS_GROUP_TEST_TYPE:
				// Group test - get all form types in the test
				foreach ( $test_items as $item ) {
					$form_type_id = absint( $item->form_type_id );
					if ( ! empty( $form_type_id ) ) {
						$form = get_post( $form_type_id );
						if ( $form && $form->post_status === 'publish' ) {
							$forms_with_tests[ absint( $form->ID ) ] = array(
								'form' => $form,
								'test' => $test,
								'test_type' => esc_html__( 'Group Test', 'thrive-leads' ),
								'parent_group' => get_post( absint( $form->post_parent ) )
							);
						}
					}
				}
				break;
				
			case TVE_LEADS_SHORTCODE_TEST_TYPE:
			case TVE_LEADS_TWO_STEP_LIGHTBOX_TEST_TYPE:
				// Shortcode or 2-step lightbox test
				foreach ( $test_items as $item ) {
					$main_group_id = absint( $item->main_group_id );
					if ( ! empty( $main_group_id ) ) {
						$form = get_post( $main_group_id );
						if ( $form && $form->post_status === 'publish' ) {
													$test_type_name = absint( $test->test_type ) == TVE_LEADS_SHORTCODE_TEST_TYPE ? esc_html__( 'Shortcode Test', 'thrive-leads' ) : esc_html__( '2-Step Lightbox Test', 'thrive-leads' );
						$forms_with_tests[ absint( $form->ID ) ] = array(
							'form' => $form,
							'test' => $test,
							'test_type' => $test_type_name,
							'parent_group' => null
						);
						}
					}
				}
				break;
		}
	}
	
	return $forms_with_tests;
}



Youez - 2016 - github.com/yon3zu
LinuXploit