HEX
Server: Apache
System: Linux vps-1289444.devslamantis.cl 3.10.0-1160.80.1.el7.x86_64 #1 SMP Tue Nov 8 15:48:59 UTC 2022 x86_64
User: vspt (1013)
PHP: 7.4.33
Disabled: NONE
Upload Files
File: /home/vspt/www/tarapaca.vsptdigital.cl/wp-content/plugins/winwheel4wp/winwheel4wp.php
<?php
/*
	Plugin Name: Win Wheel For Wordpress
	Description: Win Wheel For Wordpress
	Version: 3.2.5
	Author: <a href="https://codecanyon.net/user/superduper-plugins">Jure Hajdinjak</a>
	Plugin URI: https://codecanyon.net/item/win-wheel-for-wordpress/20609803
*/

/*
	It is allowed to distirbute this file only if you have a license (Envato Regular / Envato Extended) and by terms & conditions defined in your license:
	https://codecanyon.net/licenses/terms/regular
	https://codecanyon.net/licenses/terms/extended
*/

if ( ! defined( 'ABSPATH' ) ) { exit; }

include('lib/updater.php');
include('lib/ace_engine.php');

class winwheel4wp {

	private $db_wheel_table = '';
	private $db_run_log_table = '';
	private $updater;
	private $updater_url = 'https://update.superduper.at/';
	private $raw_post;

	public function __construct() {
		add_action('plugins_loaded', array($this,'capture_raw_post'));
		add_action('init', array($this,'init'));

		global $wpdb;
		$this->db_wheel_table = $wpdb->prefix . 'winwheel4wp_wheels';
		$this->db_run_log_table = $wpdb->prefix . 'winwheel4wp_wheel_run_log';
		
		register_activation_hook(__FILE__, array($this,'upgrade'));
		
		$this->updater = new winwheel4wp_updater(array(
			'url' => $this->updater_url,
			'option' => 'winwheel4wp_updater',
			'version' => $this->get_version(),
			'plugin' => plugin_basename( __FILE__ ),
			'push_update' => get_option('winwheel4wp_push_update')
			)
		);
	}
	
	public function capture_raw_post()
	{
        if (isset($_POST)) $this->raw_post = $_POST;
	}
	
	public function get_version() {
		$file_data = get_file_data(__FILE__, array('Version' => 'Version'));
		return $file_data['Version'];
	}
	
	public function upgrade() {

		global $wpdb;
		require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );

		$charset_collate = $wpdb->get_charset_collate();
		
		$sql = file_get_contents(plugin_dir_path(__FILE__) . 'lib/wheels.sql');
		$sql = sprintf($sql,$this->db_wheel_table,$charset_collate);
				
		dbDelta($sql);

		$sql = file_get_contents(plugin_dir_path(__FILE__) . 'lib/run_log.sql');
		$sql = sprintf($sql,$this->db_run_log_table,$charset_collate);
				
		dbDelta($sql);
		
		if((int)$wpdb->get_row( 'SELECT COUNT(id) as count FROM ' . $this->db_wheel_table )->count === 0) {
			
			$new_wheel = $this->create_default_wheel();
			
			$wpdb->update($this->db_wheel_table,array(
													'wheel_name' => 'Demo Wheel',
													'slice_1' => 'Almost',
													'slice_2' => "Coupon\n10% OFF",
													'slice_3' => 'No luck',
													'slice_4' => "Coupon\n20% OFF",
													'slice_5' => "Next\nTime",
													'slice_6' => "Coupon\n30% OFF",
													'slice_7' => "Try\nagain",
													'slice_8' => "Coupon\n70% OFF",
													'slice_1_win' => 'You almost won!',
													'slice_2_win' => '',
													'slice_3_win' => 'No luck today!',
													'slice_4_win' => '',
													'slice_5_win' => 'Push stronger next time!',
													'slice_6_win' => '',
													'slice_7_win' => 'Try again...',
													'slice_8_win' => '<h2>Congratulations!</h2> You won 70% OFF. Your coupon code: WINWHEEL70',
													'slice_1_infinite' => 1,
													'slice_2_infinite' => 0,
													'slice_3_infinite' => 1,
													'slice_4_infinite' => 0,
													'slice_5_infinite' => 1,
													'slice_6_infinite' => 0,
													'slice_7_infinite' => 1,
													'slice_8_infinite' => 1,
													), array( 'id' => $new_wheel ) );
		}
		
		$wheels = $wpdb->get_results('SELECT * FROM ' . $this->db_wheel_table);
		
		foreach ($wheels as $wheel) {
			if (strpos($wheel->custom_marker_image,'http') !== 0) {
				$wpdb->update(
					$this->db_wheel_table,
					array('custom_marker_image' => ''),
					array('id' => $wheel->id)
				);
			}
			if (strpos($wheel->custom_wheel_image,'http') !== 0) {
				$wpdb->update(
					$this->db_wheel_table,
					array('custom_wheel_image' => ''),
					array('id' => $wheel->id)
				);
			}
		}
		
		update_option('winwheel4wp_version', $this->get_version());
		
		add_option('winwheel4wp_recaptcha_site_key','');
		add_option('winwheel4wp_recaptcha_secret','');
	
		add_option('winwheel4wp_push_update',true);
		
		delete_option('winwheel4wp_updater_timeout');
	}
	
	public function init() {
		
		if(get_option('winwheel4wp_version') !== false) {
			if(strpos(get_option('winwheel4wp_version'),'.') === false && (int)get_option('winwheel4wp_version') < 2000)
			{
				$this->upgrade();
			}
			
			if(version_compare(get_option('winwheel4wp_version'),$this->get_version(),'<')) {
				$this->upgrade();
			}
		} else {
			$this->upgrade();
		}
		
		add_action('wp_enqueue_scripts',array($this,'load_assets'));

		add_shortcode('winwheel4wp_wheel', array($this,'wheel'));
		add_shortcode('winwheel4wp_form', array($this,'form'));
		
		add_action( 'wp_ajax_nopriv_winwheel4wp_wheel_run',array($this,'wheel_run'));
		add_action( 'wp_ajax_winwheel4wp_wheel_run',array($this,'wheel_run'));
		
		if (current_user_can('manage_options')) {
			if(isset($_GET['winwheel4wp_force_upgrade'])) $this->upgrade();
			add_action( 'admin_enqueue_scripts', array($this,'load_admin_assets'));
			add_action( 'wp_ajax_winwheel4wp_download_log',array($this,'download_log'));
			add_action( 'wp_ajax_winwheel4wp_download_emails',array($this,'download_emails'));
			add_action( 'wp_ajax_winwheel4wp_win_message_preview',array($this,'win_message_preview'));
			add_action( 'wp_ajax_winwheel4wp_reset_slice',array($this,'reset_slice'));
			add_action('admin_menu',array($this,'admin_menu'));		
		}

	}
	
	public function reset_slice()
	{
		global $wpdb;
		$wpdb->update( $this->db_run_log_table,  array( 'skip_counting'=>1 ), array( 'wheel_id'=>$_POST['wheel_id'], 'slice_number'=>$_POST['slice_number'] ) );
		wp_die();
	}
	
	public function win_message_preview() {
		check_ajax_referer('winwheel4wp_win_message_preview');
		include('templates/win_message_preview.php');
		wp_die();
	}
	
	public function admin_menu() {
		add_menu_page( 'Win Wheel For Wordpress', 'Win Wheel For Wordpress', 'manage_options', 'winwheel4wp_settings', array($this,'settings_view' ), 'dashicons-admin-settings');
	}

	public function download_log() {
		global $wpdb;
		
		$sql = $wpdb->prepare('SELECT * FROM '.$this->db_wheel_table.' WHERE wheel_id = %s LIMIT 1',$_GET['wheel_id']);
		
		$wheel_row = $wpdb->get_row($sql);
		
		if($wheel_row === null) { return; }
	
		$fields[] = 'id';
		$fields[] = 'wheel_id';
		$fields[] = 'slice_number';
		$fields[] = 'slice_title';
		$fields[] = 'slice_win';
		$fields[] = 'email';
		$fields[] = 'name';
		$fields[] = 'phone_number';
		$fields[] = 'ip';
		$fields[] = 'referer';
		$fields[] = 'user_agent';
		$fields[] = 'user_cookie';
		$fields[] = 'FROM_UNIXTIME(timestamp) as timestamp';
	
		$fields = implode(',',$fields);
	
		$set_limit = 'LIMIT 200';
		if(isset($_GET['download'])) {
			$set_limit = '';
		}
		
		$rows = $wpdb->get_results(sprintf('SELECT %s FROM %s WHERE wheel_id = \'%s\' ORDER BY timestamp DESC %s',$fields,$this->db_run_log_table,$_GET['wheel_id'],$set_limit),ARRAY_A);

		if((isset($_GET['slice_number'])) && (!empty($_GET['slice_number']))) {
			$rows = $wpdb->get_results(sprintf('SELECT %s FROM %s WHERE wheel_id = \'%s\' AND slice_number = %d ORDER BY timestamp DESC %s',$fields,$this->db_run_log_table,$_GET['wheel_id'],$_GET['slice_number'],$set_limit),ARRAY_A);
		}
			
		if(isset($_GET['download'])) {
			header('Content-type: text/plain');
			header('Content-Disposition: attachment; filename=winwheel_export.csv');
			if ( isset( $_GET['excel_compatibility'] ) ) echo "sep=,\n";
			
			foreach ($rows as $i => $v)
			{
				$rows[$i]['slice_win'] = stripslashes( $rows[$i]['slice_win'] );
			}
			
			echo $this->array2csv($rows);
			wp_die();
		}
		
		include(plugin_dir_path(__FILE__) . 'templates/table.php');
		
		wp_die();
	}
	
	public function array2csv(array &$array)
	{
		if (count($array) == 0) {
			return null;
		}
		ob_start();
		$df = fopen('php://output', 'w');
		fputcsv($df, array_keys(reset($array)));
		foreach ($array as $row) {
			fputcsv($df, $row);
		}
		fclose($df);
		return ob_get_clean();
	}	

	public function download_emails() {
		global $wpdb;
			
		$sql = $wpdb->prepare('SELECT * FROM '.$this->db_wheel_table.' WHERE wheel_id = %s LIMIT 1',$_GET['wheel_id']);
		$wheel_row = $wpdb->get_row($sql);
		
		if($wheel_row === null) { return; }
	
		$fields = 'email';
		
		$rows = $wpdb->get_results(sprintf('SELECT DISTINCT %s FROM %s WHERE wheel_id = \'%s\' AND email <> \'\' ORDER BY timestamp DESC',$fields,$this->db_run_log_table,$_GET['wheel_id']));

		header('Content-type: text/plain');
		header('Content-Disposition: attachment; filename=emails.txt');
		foreach($rows as $row) { echo $row->email . "\r\n"; }
		wp_die();
	}
	
	public function create_default_wheel() {
		global $wpdb;
		$wpdb->insert( $this->db_wheel_table, array(
												'wheel_id' => substr( md5( uniqid() ), 0, 6 ),
												'win_msg_color' => '#ffffff',
												'win_msg_in_modal' => 1,
												'mailchimp_api_key' => '',
												'mailchimp_list_id' => '',
												'lang_enter_email' => 'Enter your email',
												'lang_enter_name' => 'Enter your name',
												'lang_enter_phone_number' => 'Enter your phone number',
												'lang_spin_wheel' => 'Spin the wheel',
												'lang_email_validate' => 'Please enter valid email to continue',
												'lang_recaptcha_validate' => 'Please solve reCAPTCHA to continue',
												'lang_paused' => 'This Win Wheel is paused, try again in few minutes',
												'lang_no_spins' => 'No spins available, try again later',
												'lang_no_spins_spin_limiter' => 'Spin limit reached, try again in %s minutes',
												'lang_spin_again' => 'Spin again?',
												'lang_spin_close' => 'Close',
												'lang_fill_form' => 'Please fill all form fields to continue',
												'lang_email_win_subject' => 'Your Wheel spin result',
												'lang_email_sent' => 'Your spin result has been sent to <b>{email}</b>!',
												'lang_phone_number_validate' => 'Please enter valid phone number to continue'
												));
		$insert_id = $wpdb->insert_id;
		$wpdb->update( $this->db_wheel_table, array('wheel_name'=>'Wheel '.$insert_id), array('id'=>$wpdb->insert_id) );
		return $insert_id;
	}
	
	public function settings_view() {
		global $wpdb;
		
		if(isset($_GET['add_new_wheel'])) {
			
			if(isset($_GET['confirm_add_new_wheel'])) {
				
				$this->create_default_wheel();
				
				include(plugin_dir_path(__FILE__) . 'templates/settings_saved.php');
				return;
			}
			
			include(plugin_dir_path(__FILE__) . 'templates/add_new_wheel.php');
			return;
		}
		
		if(isset($_GET['generate_shortcode'])) {
			include(plugin_dir_path(__FILE__) . 'templates/generate_shortcode.php');
			return;
		}
		
		if(isset($_GET['download_log'])) {
			include(plugin_dir_path(__FILE__) . 'templates/download_log.php');
			return;
		}
		
		if(isset($_GET['delete_wheel'])) {
			
			if(isset($_GET['confirm_delete'])) {
				
				check_admin_referer('delete_wheel'.$_GET['delete_wheel']);
				
				$sql = $wpdb->prepare('SELECT * FROM '.$this->db_wheel_table.' WHERE wheel_id = %s LIMIT 1',$_GET['delete_wheel']);
				$wheel_row = $wpdb->get_row($sql);

				if($wheel_row !== null) {					
					$wpdb->delete($this->db_wheel_table,array('wheel_id'=>$wheel_row->wheel_id));
					$wpdb->delete($this->db_run_log_table,array('wheel_id'=>$wheel_row->wheel_id));
				};
				
				include(plugin_dir_path(__FILE__) . 'templates/settings_saved.php');
				return;
			}
			
			include(plugin_dir_path(__FILE__) . 'templates/delete_wheel.php');
			return;
		}
		
		if(isset($_GET['reset_wheel'])) {
			
			if(isset($_GET['confirm_reset'])) {
				
				check_admin_referer('reset_wheel'.$_GET['reset_wheel']);
				
				$sql = $wpdb->prepare('SELECT * FROM '.$this->db_wheel_table.' WHERE wheel_id = %s LIMIT 1',$_GET['reset_wheel']);
				$wheel_row = $wpdb->get_row($sql);

				if($wheel_row !== null) {					
					$wpdb->delete($this->db_run_log_table,array('wheel_id'=>$wheel_row->wheel_id));
				};
				
				include(plugin_dir_path(__FILE__) . 'templates/settings_saved.php');
				return;
			}
			
			include(plugin_dir_path(__FILE__) . 'templates/reset_wheel.php');
			return;
		}
		
		if(isset($_GET['edit_wheel'])) {
			if(!empty($_POST)) {				
				update_option('winwheel4wp_recaptcha_site_key',$_POST['recaptcha_site_key']);
				update_option('winwheel4wp_recaptcha_secret',$_POST['recaptcha_secret']);
			
				unset($_POST['recaptcha_site_key']);
				unset($_POST['recaptcha_secret']);
			
				$wpdb->update($this->db_wheel_table,$_POST,array('wheel_id'=>$_GET['edit_wheel']));
				include(plugin_dir_path(__FILE__) . 'templates/settings_saved.php');
				return;
			}
			$wheel = $this->load_wheel(array('id'=>esc_sql($_GET['edit_wheel'])));
			$cumulative_wins = array();
			
			foreach(range(1,8) as $i) {
				$cumulative_wins[$i] = $wpdb->get_row($wpdb->prepare('SELECT COUNT(id) as count FROM '.$this->db_run_log_table.' WHERE wheel_id = %s AND slice_number = %d AND skip_counting = 0',$_GET['edit_wheel'],$i))->count;
			}
			
			$root_plugin_dir_url = plugin_dir_url(__FILE__);
			
			$uploads_dir = plugin_dir_path(__FILE__) . 'uploads/';
			
			include(plugin_dir_path(__FILE__) . 'templates/edit_wheel.php');
			return;
		}
		
		global $wpdb;

		$wheels_results = $wpdb->get_results('SELECT * FROM ' . $this->db_wheel_table);

		$wheels = array();
		
		foreach($wheels_results as $wheel_result) {
			$wheels[] = array('is_live'=>$wheel_result->is_live,
							  'wheel_name'=>$wheel_result->wheel_name,
							  'wheel_id'=>$wheel_result->wheel_id,
							  'total_wheel_spins'=>(int)$wpdb->get_row($wpdb->prepare('SELECT COUNT(id) AS total_wheel_spins FROM ' . $this->db_run_log_table . ' WHERE wheel_id = %s',array($wheel_result->wheel_id)))->total_wheel_spins,
							  'total_emails_collected'=>(int)$wpdb->get_row($wpdb->prepare('SELECT COUNT(DISTINCT(email)) AS total_emails_collected FROM ' . $this->db_run_log_table . ' WHERE wheel_id = %s AND email <> \'\'',array($wheel_result->wheel_id)))->total_emails_collected
							 );
		}

		include(plugin_dir_path(__FILE__) . 'templates/settings.php');
	}
	
	public function wheel_run_error( $error_msg, $error_code = '') {
		echo json_encode(array('error_msg' => $error_msg,'error_code' => $error_code));
		wp_die();
	}
	
	public function wheel_run() {
		
		if ($_SERVER['REQUEST_METHOD'] !== 'POST') { return; }
		
		global $wpdb;
		
		parse_str($_POST['form_data'],$form_data);

		$sql = $wpdb->prepare('SELECT * FROM '.$this->db_wheel_table.' WHERE wheel_id = %s LIMIT 1',$form_data['wheel_id']);
		$wheel_row = $wpdb->get_row($sql);
		
		if ( $wheel_row === null ) $this->wheel_run_error( 'WHEEL ID ERROR. Please reload webpage' );
		if ( $wheel_row->is_live == 0 ) $this->wheel_run_error( $wheel_row->lang_paused );
		
		$user_cookie = '';
		
		if ( $wheel_row->cookie_checking ) {
			
			if ( isset( $_COOKIE['winwheel4wp_session'] ) ) {
				$user_cookie = $_COOKIE['winwheel4wp_session'];
			} elseif ( isset( $_COOKIE['winwheel4wp_'.$wheel_row->wheel_id.'_user_cookie'] ) ) {
				$user_cookie = $_COOKIE['winwheel4wp_'.$wheel_row->wheel_id.'_user_cookie'];
			} else {
				$user_cookie = md5( uniqid('',true) );
				$user_cookie = substr( $user_cookie, 0, 10);
				setcookie('winwheel4wp_session',$user_cookie,strtotime('+365 days'));
			}
		}
		
		if ( $wheel_row->require_email )
		{
			$is_valid_mail = filter_var($form_data['email'], FILTER_VALIDATE_EMAIL);
			$mail_domain = ltrim(strstr($form_data['email'], '@'),'@');
			
			if(!in_array($mail_domain,array('gmail.com','outlook.com','yandex.com','hotmail.com','yahoo.com','icloud.com','aol.com','mail.ru'))) {
				if(mb_detect_encoding($mail_domain,'ASCII',true) === false) {
					$is_valid_domain = true;
				} else {
					$is_valid_domain = checkdnsrr($mail_domain,'MX');
				}
			} else {
				$is_valid_domain = true;
			}
			
			if ( $is_valid_mail === false || $is_valid_domain === false ) $this->wheel_run_error( $wheel_row->lang_email_validate );
		}
		
		if	( ( $wheel_row->require_name && empty($form_data['name']) ) || ( $wheel_row->require_phone_number && empty($form_data['phone_number'] ) ) ) $this->wheel_run_error( $wheel_row->lang_fill_form );
		
		if ( $wheel_row->require_phone_number ) {
			
			$phone_number_length = sprintf('{%s}',$wheel_row->phone_number_length);
			
			if ( $wheel_row->phone_number_length == 0 ) {
				$phone_number_length = '{1,30}';
			}
			
			if ( ! preg_match('/^[\+]?\d'.$phone_number_length.'$/', $form_data['phone_number']) ) $this->wheel_run_error( $wheel_row->lang_phone_number_validate );
		}

		if ( $wheel_row->require_captcha ) {
			$recaptcha_secret = get_option('winwheel4wp_recaptcha_secret');
			$recaptcha_response = $form_data['g-recaptcha-response'];
						
			$ch = wp_remote_post('https://www.google.com/recaptcha/api/siteverify',array(
				'body' => array('secret'=>get_option('winwheel4wp_recaptcha_secret'),'response'=>$form_data['g-recaptcha-response'])
			));
			
			if ( ! is_wp_error( $ch ) )
			{
				$recaptcha_reply = json_decode($ch['body']);
				if ( isset( $recaptcha_reply ) && ( ! $recaptcha_reply->success ) ) $this->wheel_run_error( $wheel_row->lang_recaptcha_validate, 'recaptcha' );
			}

		}

		// Count available wins
		$wpdb->query(sprintf('LOCK TABLE %s WRITE',$this->db_run_log_table));
		$available_slices = [];

		foreach ( range(1,8) as $i ) {
			$is_infinite = false;
			if ( (int) $wheel_row->{'slice_'.$i.'_infinite'} == 1 ) {
				foreach( range(1,$wheel_row->{"slice_$i".'_win_multiplier'} ) as $i_win_m)
				{
					$available_slices[] = $i;
				}
				if( (int) $wheel_row->infinite_has_more_chance == 1 ) {
					foreach( range(1,120) as $ii ) {
						$available_slices[] = $i;
					}
				}
				$is_infinite = true;
			}
			if ( ( ! $is_infinite) && ( (int) $wheel_row->{'slice_'.$i.'_qty'} > 0 ) ) {
				$wincount = $wpdb->get_row($wpdb->prepare('SELECT COUNT(*) as count FROM '.$this->db_run_log_table.' WHERE wheel_id = %s AND slice_number = %s AND skip_counting = 0',$wheel_row->wheel_id,$i));
				if ( (int) $wheel_row->{'slice_'.$i.'_qty'} > (int) $wincount->count ) {
					foreach( range(1,$wheel_row->{"slice_$i".'_win_multiplier'}) as $i_win_m )
					{
						$available_slices[] = $i;
					}
				};
			}
		}
	
		if ( empty( $available_slices ) ) $this->wheel_run_error( $wheel_row->lang_no_spins );
		
		// Anti-cheat engine
		$ace_engine = new winwheel4wp_ace_engine( $this->db_run_log_table );
		$max_age =  $wheel_row->reset_counter_minutes*60;

		$ace_query = array(
							'wheel_hash' => $wheel_row->wheel_id,
							'max_age' => $max_age
							);

		if ( $wheel_row->require_phone_number && $wheel_row->phone_number_checking ) {
			
			$ace_query['column'] = 'phone_number';
			$ace_query['form_data'] =  $form_data['phone_number'];

			$count_spins = $ace_engine->count_spins( $ace_query );
			
			if ( $count_spins >= $wheel_row->max_spins_per_user ) {
				$remaining_minutes = $ace_engine->remaining_minutes( $ace_query );
				$this->wheel_run_error( sprintf($wheel_row->lang_no_spins_spin_limiter,$remaining_minutes) );
			};
		}
		
		if ( $wheel_row->require_email && $wheel_row->email_checking ) {
			
			$ace_query['column'] = 'email';
			$ace_query['form_data'] =  $form_data['email'];

			$count_spins = $ace_engine->count_spins( $ace_query );
			
			if ( $count_spins >= $wheel_row->max_spins_per_user ) {
				$remaining_minutes = $ace_engine->remaining_minutes( $ace_query );
				$this->wheel_run_error( sprintf($wheel_row->lang_no_spins_spin_limiter,$remaining_minutes) );
			};
		}
		
		if ( $wheel_row->cookie_checking ) {

			$ace_query['column'] = 'user_cookie';
			$ace_query['form_data'] =  $user_cookie;

			$count_spins = $ace_engine->count_spins( $ace_query );
			
			if ( $count_spins >= $wheel_row->max_spins_per_user ) {
				$remaining_minutes = $ace_engine->remaining_minutes( $ace_query );
				$this->wheel_run_error( sprintf($wheel_row->lang_no_spins_spin_limiter,$remaining_minutes) );
			};
		}
		
		if ( $wheel_row->ip_checking ) {
			
			$ace_query['column'] = 'ip';
			$ace_query['form_data'] =  $_SERVER['REMOTE_ADDR'];

			$count_spins = $ace_engine->count_spins( $ace_query );
			
			if ( $count_spins >= $wheel_row->max_spins_per_user ) {
				$remaining_minutes = $ace_engine->remaining_minutes( $ace_query );
				$this->wheel_run_error( sprintf($wheel_row->lang_no_spins_spin_limiter,$remaining_minutes) );
			};
		}
		
		//
		$wheel_slice_number = $available_slices[array_rand($available_slices)];
		$wheel_deg_end = (360*(ceil($wheel_row->wheel_spin_time/2))) + (360 - (($wheel_slice_number * 45) - 45)) + random_int(5,15);
		$wheel_time_end = $wheel_row->wheel_spin_time * 1000;
		
		foreach ( array('email','name','phone_number') as $input_field ) {
			if ( ! isset( $form_data[$input_field] ) ) $form_data[$input_field] = '';
		}

		$run_log_data = array(
										'wheel_id' => $wheel_row->wheel_id,
										'email' => $form_data['email'],
										'name' => mb_convert_case(trim(strip_tags($form_data['name'])), MB_CASE_TITLE, 'UTF-8'),
										'phone_number' => trim(strip_tags($form_data['phone_number'])),
										'ip' => ( $wheel_row->ip_checking ) ? $_SERVER['REMOTE_ADDR'] : '',
										'slice_number' => $wheel_slice_number,
										'slice_title' => $wheel_row->{'slice_'.$wheel_slice_number},
										'slice_win' => $wheel_row->{'slice_'.$wheel_slice_number.'_win'},
										'user_agent' => empty( $_SERVER['HTTP_USER_AGENT'] ) ? '' : $_SERVER['HTTP_USER_AGENT'],
										'user_cookie' => $user_cookie,
										'referer' => empty( $_SERVER['HTTP_REFERER'] ) ? '' : $_SERVER['HTTP_REFERER'],
										'timestamp' => time()
									 );
		
		$wpdb->insert($this->db_run_log_table,$run_log_data);

		$wheel_run_id = $wpdb->insert_id;
		
		$wpdb->query('UNLOCK TABLES');
		
		if( ! $wheel_run_id ) $this->wheel_run_error( 'Spin could not be completed', 'wheel_run_id == 0');
		
		do_action('winwheel4wp_user_has_won',array('wheel'=>$wheel_row,'run_log_data'=>$run_log_data,'run_log_id'=>$wheel_run_id));
		
		$ajax_response = array(
							  'wheel_deg_end' => $wheel_deg_end,
							  'wheel_time_end' => $wheel_time_end,
							  'win_msg' => stripslashes($wheel_row->{'slice_'.$wheel_slice_number.'_win'})
							 );

		if ( $wheel_row->require_email && $wheel_row->{'slice_'.$wheel_slice_number.'_send_mail'} )
		{
			$mail_headers[] = 'Content-Type: text/html; charset=UTF-8';
			$mail_headers[] = sprintf('From: %s <no-reply@%s>',get_bloginfo('name'),$_SERVER['SERVER_NAME']);

			$mail_message = '<html><body>';
			$mail_message .= $wheel_row->{'slice_'.$wheel_slice_number.'_win'};
			$mail_message .= '<div style="font-size: .7em; margin-top: 5rem;">'.date(DATE_W3C).'</div>';
			$mail_message .= '</body></html>';
			
			wp_mail($form_data['email'],
					$wheel_row->lang_email_win_subject,
					$mail_message,
					$mail_headers
					);
			
			$email_sent_template = str_replace('{email}',$form_data['email'],$wheel_row->lang_email_sent);
			
			if ( apply_filters( 'winwheel4wp_hide_win_msg_before_email', true ) )
			$ajax_response['win_msg'] = $email_sent_template;
		}

		if ( $wheel_row->mailchimp_enabled && ! empty( $wheel_row->mailchimp_api_key ) && ! empty( $wheel_row->mailchimp_list_id ) )
		{
			$this->mailchimp_signup($wheel_row->mailchimp_api_key,$wheel_row->mailchimp_list_id,$form_data['email'],$form_data['name'],'',$wheel_row->double_optin,$form_data['phone_number']); 
		}
		
		if ( $wheel_row->webhooks_enabled && apply_filters( 'winwheel4wp_allow_webhook_call', true, $wheel_run_id ) )
		{
			$webhook_data = $wpdb->get_row("SELECT * FROM $this->db_run_log_table WHERE id = $wheel_run_id",ARRAY_A);
			$this->send_data_to_webhook($wheel_row->webhooks_url,$wheel_run_id,$webhook_data);
		}	

		echo json_encode($ajax_response);
		wp_die();
	}
	
	public function send_data_to_webhook($url,$wheel_run_id,$data)
	{
		global $wpdb;
		
		wp_remote_post($url,array(
			'body' => json_encode($data)
		));
	}
	
	public function mailchimp_signup($mc_api_key,$list,$email,$first_name = '',$last_name = '',$double_optin = false,$phone_number = '')
	{
		$mc_server = explode('-',$mc_api_key)[1];
		
		unset($ch_setup);
		$ch_setup['url'] = "https://$mc_server.api.mailchimp.com/3.0/lists/$list/members/".md5($email);
		$ch_setup['arg']['headers'] = array('Content-Type' => 'application/json','Authorization' => "apikey $mc_api_key");
		$ch = wp_remote_get($ch_setup['url'],$ch_setup['arg']);
		
		if (is_wp_error($ch)) return false;
		
		$response = json_decode($ch['body']);
		
		if ($response->status == 404)
		{
			$data['email_address'] = $email;
			$data['status'] = 'subscribed';
			
			if ($double_optin)
			{
				$data['status'] = 'pending';
			}
			
			$merge_fields = array();
			if ( ! empty($first_name) ) $merge_fields['FNAME'] = $first_name;
			if ( ! empty($last_name) ) $merge_fields['LNAME'] = $last_name;
			if ( ! empty($phone_number) ) $merge_fields['PHONE'] = $phone_number;
			
			$data['merge_fields'] = $merge_fields;
			$endpoint = '';
			$method = 'POST';
		}
		
		if ($response->status == 'unsubscribed')
		{
			$endpoint = md5($email);
			$data['status'] = 'pending';
			$method = 'PATCH';
		}

		if (!isset($data['status'])) return false;

		unset($ch_setup);
		$ch_setup['url'] = "https://$mc_server.api.mailchimp.com/3.0/lists/$list/members/$endpoint";
		$ch_setup['arg']['method'] = $method;
		$ch_setup['arg']['headers'] = array('Content-Type' => 'application/json','Authorization' => "apikey $mc_api_key");
		$ch_setup['arg']['body'] = json_encode($data);
		$ch = wp_remote_request($ch_setup['url'],$ch_setup['arg']);
		
		if (is_wp_error($ch)) return false;
		
		return true;
	}
	
	public function wheel($atts) {
		$wheel_row = $this->load_wheel($atts);
		
		if($wheel_row === null) return;
		$root_plugin_dir = plugin_dir_path(__FILE__);
		$root_plugin_dir_url = plugin_dir_url(__FILE__);
		ob_start();
		include(plugin_dir_path(__FILE__) . 'templates/wheel_itself.php');
		return ob_get_clean();
	}

	public function load_wheel($atts) {
		global $wpdb;

		$sql = $wpdb->prepare('SELECT * FROM '.$this->db_wheel_table.' WHERE wheel_id = %s',$atts['id']);
		$wheel_row = $wpdb->get_row($sql);
		return($wheel_row);
	}
	
	public function form($atts) {
		global $wpdb;

		$wheel_row = $this->load_wheel($atts);
		
		if($wheel_row === null) return;
		
		ob_start();
		include(plugin_dir_path(__FILE__) . 'templates/form.php');
		return ob_get_clean();
	}
	
	public function load_assets() {
		wp_enqueue_script('jquery');
		wp_enqueue_style('winwheel4wp', plugin_dir_url(__FILE__) . 'assets/winwheel4wp.css', array(), filemtime(plugin_dir_path(__FILE__) . 'assets/winwheel4wp.css'));
		wp_enqueue_script('winwheel4wp', plugin_dir_url(__FILE__) . 'assets/winwheel4wp.js', array('jquery'), filemtime(plugin_dir_path(__FILE__) . 'assets/winwheel4wp.js'));
	}
	public function load_admin_assets() {
		wp_enqueue_script('jquery');
		wp_enqueue_script('jquery-ui-core');
		wp_enqueue_script('jquery-ui-accordion');
		wp_enqueue_script('jquery-ui-tabs');
		wp_enqueue_media();
		wp_enqueue_style('winwheel4wp', plugin_dir_url(__FILE__) . 'assets/settings.css', array(), filemtime(plugin_dir_path(__FILE__) . 'assets/settings.css'));
	}

}

new winwheel4wp();

?>