<?php
/**
 * Functions for various GiveASAP actions
 */

use Simple_Giveaways\SG_Giveaway;
use Simple_Giveaways\SG_Giveaway_Factory;
use Simple_Giveaways\SG_Subscriber;

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

/**
 * Get a Giveaway
 *
 * @param int|WP_Post $post
 *
 * @return SG_Giveaway
 */
function giveasap_get_giveaway( $post ) {
	return SG_Giveaway_Factory::get_giveaway( $post );
}

/**
 * Get giveaways.
 *
 * @return array
 */
function giveasap_get_giveaways( $args = array() ) {
	$args = wp_parse_args(
		$args,
		array(
			'post_type'      => 'giveasap',
			'post_status'    => 'publish',
			'posts_per_page' => -1,
		)
	);

	return get_posts( $args );
}

/**
 * Get Giveaway Types.
 *
 * @since 2.20.0 was giveasap_get_giveaways() before.
 *
 * @return array
 */
function giveasap_get_giveaway_types() {
	return apply_filters(
		'giveasap_get_giveaway_types',
		array(
			'simple'             => __( 'Simple', 'giveasap' ),
			'limited'            => __( 'Limited', 'giveasap' ),
			'logged_in'          => __( 'Only Logged In Users', 'giveasap' ),
			'no_subscriber_page' => __( 'Not Showing Subscriber Page', 'giveasap' ),
			'evergreen'          => __( 'Evergreen', 'giveasap' ),
			'user_picker'        => __( 'Pick a Registered User', 'giveasap' ),
		)
	);
}

add_action( 'giveasap_has_ended', 'giveasap_has_ended', 10 );
/**
 * Function to be used in a scheduled action 'giveasap_had_ended'
 *
 * @param  int $post_id ID of the giveaway
 * @return void
 */
function giveasap_has_ended( $post_id ) {
	giveasap_set_status( $post_id, 'giveasap', 'giveasap_ended' );
}

add_action( 'giveasap_remind_subscribers', 'giveasap_remind_subscribers', 10 );

/**
 * Remind Subscribers about the giveaway
 *
 * @param integer $post_id
 *
 * @since 2.31.0
 */
function giveasap_remind_subscribers( $post_id ) {
	$entries = giveasap_get_active_entries_for( $post_id );
	if ( $entries ) {
		foreach ( $entries as $entry ) {
			giveasap_send_reminder_email( $entry->id, $post_id );
		}
	}
}

/**
 * Return if the GDPR is active.
 *
 * @return bool
 */
function giveasap_is_gdpr_active() {
	$settings = giveasap_get_settings();

	return isset( $settings['gdpr_active'] ) ? (bool) $settings['gdpr_active'] : false;
}

/**
 * Return a encoded method title.
 *
 * @param $title
 *
 * @since 2.12.0
 *
 * @return string
 */
function giveasap_get_encoded_method_title( $title ) {
	return base64_encode( 'sg_sharing_' . sanitize_title( $title ) );
}

/**
 * Return only the method slug from the encoded method title.
 *
 * @param $title
 *
 * @return mixed
 */
function giveasap_get_decoded_method_title( $title ) {
	$decoded = base64_decode( $title );
	return str_replace( 'sg_sharing_', '', $decoded );
}

/**
 * Return registered sharing methods
 *
 * @since 2.10.0
 */
function giveasap_get_registered_sharing_methods() {
	return apply_filters( 'giveasap_sharing_methods', array() );
}

/**
 * Return saved sharing methods
 *
 * @since 2.10.0
 */
function giveasap_get_saved_sharing_methods() {
	$settings = giveasap_get_settings();
	return isset( $settings['giveasap_methods'] ) ? $settings['giveasap_methods'] : array(
		array(
			'type'  => 'giveasap_facebook',
			'title' => __( 'Facebook', 'giveasap' ),
		),
		array(
			'type'  => 'giveasap_twitter',
			'title' => __( 'X (Twitter)', 'giveasap' ),
		),
		array(
			'type'  => 'giveasap_linkedin',
			'title' => __( 'LinkedIN', 'giveasap' ),
		),
		array(
			'type'  => 'giveasap_pinterest',
			'title' => __( 'Pinterest', 'giveasap' ),
		),
		array(
			'type'  => 'giveasap_link',
			'title' => __( 'Link', 'giveasap' ),
		),
	);
}

/**
 * Return sharing methods for rendering.
 */
function giveasap_get_sharing_methods() {
	$registered_methods = giveasap_get_registered_sharing_methods();
	$saved_methods      = giveasap_get_saved_sharing_methods();
	$methods            = array();
	if ( $saved_methods ) {
		foreach ( $saved_methods as $method ) {
			if ( isset( $registered_methods[ $method['type'] ] ) ) {
				$class     = $registered_methods[ $method['type'] ];
				$methods[] = new $class( $method );
			}
		}
	}

	return $methods;
}

/**
 * Notify Winners by getting all the winners and sending them the email set in the giveaway
 *
 * @param  array          $winners Array of Winners
 * @param  int            $post_id ID of the giveaway
 * @param  string|boolean $subscriber If provided, it will only notify that one.
 * @return void
 */
function giveasap_notify_winners( $winners, $post_id, $subscriber = false ) {
	// Get texts settings
	$texts = get_post_meta( $post_id, 'giveasap_text', true );
	// Prize settings
	$prize_options = get_post_meta( $post_id, 'giveasap_prize', true );

	// Email
	$email_text = $texts['winner_email'];
	// Replace the title placeholder
	$email_text = str_replace( '{{TITLE}}', $prize_options['prize'], $email_text );

	/**
	 * Getting the email subject from the text options
	 * If it's set in the array, use it, if not set a default one.
	 *
	 * @since  2.6.2
	 *
	 * @var [type]
	 */
	$email_subject = isset( $texts['winner_subject'] ) ? $texts['winner_subject'] : sprintf( __( 'Congratulations, you have won %s', 'giveasap' ), $prize_options['prize'] );

	if ( ! $email_subject ) {
		return;
	}

	// Subject Title
	$email_subject = str_replace( '{{TITLE}}', $prize_options['prize'], $email_subject );
	$form_fields   = giveasap_get_form_fields( $post_id );
	// Email for every winner.
	foreach ( $winners as $order => $winner ) {
		if ( 'no' === $winner['emailed'] ) {
			if ( false === $subscriber || $subscriber === $winner['email'] ) {
				$subscriber_id     = empty( $winner['id'] ) ? 0 : $winner['id'];
				$winner_email_text = apply_filters( 'sg_winner_email_text', $email_text, $winner, $order, $post_id, $prize_options );
				$winner_subject    = $email_subject;
                $winner_subscriber = giveasap_get_subscriber( $subscriber_id, $post_id );

                if ( $winner_subscriber->is_unsubscribed_from_emails() ) {
                    // Break on first.
                    if ( $subscriber === $winner['email'] ) {
                        break;
                    }
                    continue;
                }

				if ( $form_fields ) {
					foreach ( $form_fields as $field_key => $field_config ) {
						$form_value = $subscriber_id ? giveasap_get_meta( $subscriber_id, '_' . $field_key, true ) : '';
						if ( ! $form_value ) {
							$form_value = '';
						}

						$winner_subject    = str_replace( '{{FORM_' . strtoupper( $field_key ) . '}}', $form_value, $winner_subject );
						$winner_email_text = str_replace( '{{FORM_' . strtoupper( $field_key ) . '}}', $form_value, $winner_email_text );
					}
				}

				$mail_bool = giveasap_mail( $winner['email'], $winner_subject, $winner_email_text );
				if ( $mail_bool ) {
					$winner['emailed'] = 'yes';
					$winners[ $order ] = $winner;
				}

				// Break on first.
				if ( $subscriber === $winner['email'] ) {
					break;
				}
			}
		}
	}

	giveasap_update_winners( $winners, $post_id );

	do_action( 'giveasap_notify_winners', $winners, $post_id, $subscriber );
}

/**
 * Used for filtering the wp_mail by setting the content in a HTML type
 *
 * @param  string $content_type
 * @return string
 */
function giveasap_set_mail_content_type( $content_type ) {
	return 'text/html';
}

/**
 * Select the winners
 *
 * @param  number $post_id
 * @return mixed  Return array of winner's emails or if not any, returns false
 */
function giveasap_select_winner( $post_id ) {
	$giveaway = giveasap_get_giveaway( $post_id );

	// Giveaway
	if ( $giveaway->supports( 'winner_threshold' ) || $giveaway->supports( 'prize_threshold' ) ) {
		return false;
	}

	// Prize settings
	$prize_options = $giveaway->get_prize_settings();
	// Number of winners
	$number_of_winners = (int) $prize_options['winners'];

	if ( giveasap_is_activation_required() ) {
		// Get the entries
		$registered_entries = giveasap_get_active_entries_for( $post_id );
	} else {
		// Get the entries
		$registered_entries = giveasap_get_entries_for( $post_id );
	}

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

	$type = isset( $prize_options['type'] ) ? $prize_options['type'] : 'default';

	// Removing winner meta and blocked entries.
	foreach ( $registered_entries as $index => $entry ) {

		giveasap_delete_meta( $entry->id, 'winner' );

		// In case we get some entries that are blocked. Remove them.
		if ( 'blocked' === $entry->status ) {
			unset( $registered_entries[ $index ] );
		}
	}

	if ( 'random' === $type ) {
		$entries = array();
		foreach ( $registered_entries as $entry ) {
			for ( $i = 0; $i < $entry->entries; $i++ ) {
				$entries[] = $entry;
			}
		}
		$registered_entries = $entries;
	}

	$registered_entries = apply_filters( 'giveasap_select_winner_entries_before_shuffle', $registered_entries, $post_id, $prize_options );

	// Shuffle the array
	shuffle( $registered_entries );

	$winner_entries = array();

	if ( 'default' === $type ) {
		// Sort it from high to low
		usort( $registered_entries, 'giveasap_sort_entries' );

		// Splice the array to get the first entries from 1 to number of winners
		$winner_entries = array_splice( $registered_entries, 0, $number_of_winners );
	}

	if ( 'random' === $type ) {
		$winner_entries = array();
		foreach ( $registered_entries as $entry ) {

			if ( count( $winner_entries ) >= $number_of_winners ) {
				break;
			}

			if ( isset( $winner_entries[ $entry->id ] ) ) {
				continue;
			}

			$winner_entries[ $entry->id ] = $entry;
		}
	}

	$winner_entries = apply_filters( 'giveasap_select_winner_entries', $winner_entries, $post_id, $prize_options );

	$selected_winners = array();

	// If there are any winner entries, get the email from each.
	if ( ! empty( $winner_entries ) ) {
		foreach ( $winner_entries as $user ) {
			$selected_winners[] = array(
				'id'      => $user->id,
				'email'   => $user->email,
				'emailed' => 'no',
			);
			giveasap_update_meta( $user->id, 'winner', '1' );
		}

		$selected_winners = apply_filters( 'sg_selected_winners', $selected_winners, $post_id, $giveaway );
		giveasap_update_winners( $selected_winners, $post_id );

		/**
		 * Winners were selected
		 *
		 * @since  2.2.0
		 *
		 * @param  int   $post_id The ID of the Giveaway
		 * @param  array $selected_winners Array of Winner Emails
		 */
		do_action( 'giveasap_selected_winners', $post_id, $selected_winners );

		return $selected_winners;
	}
	return false;
}

/**
 * Sorting array values
 *
 * @return number 0 - remains in position, 1 -> moves up, -1 -> moves down
 */
function giveasap_sort_entries( $item_a, $item_b ) {

	if ( absint( $item_a->entries ) === absint( $item_b->entries ) ) {
		return 0;
	}

	return ( absint( $item_a->entries ) > absint( $item_b->entries ) ) ? -1 : 1;

}

/**
 * Updating the data for winners
 *
 * @param  array $winners
 * @param  int   $post_id
 * @return void
 */
function giveasap_update_winners( $winners, $post_id ) {
	update_post_meta( $post_id, 'giveasap_winners', $winners );
}

/**
 * Returning the winners
 *
 * @param  int $post_id
 * @return array
 */
function giveasap_get_winners( $post_id ) {
	return get_post_meta( $post_id, 'giveasap_winners', true );
}

/**
 * Returning all the registered users
 *
 * @param  int $post_id
 *
 * @return array
 *
 * @deprecated 2.0.0
 */
function giveasap_get_users( $post_id ) {
	return get_post_meta( $post_id, 'giveasap_registered_users', true );
}

/**
 * Setting the status to a giveaway
 *
 * @param  int    $post_id
 * @param  string $post_type      Post Type which status we want to update
 * @param  string $status         Status to update
 * @param  string $from_status    From which status
 * @return bool                     True if updated, false if not
 */
function giveasap_set_status( $post_id, $post_type, $status, $from_status = 'publish' ) {
	if ( get_post_type( $post_id ) === $post_type ) {
		global $wpdb;

		$update_status = $wpdb->update(
			$wpdb->posts,
			array(
				'post_status' => $status,  // string
			),
			array(
				'ID'          => intval( $post_id ),
				'post_type'   => $post_type,
				'post_status' => $from_status,
			),
			array(
				'%s',   // value1
			),
			array( '%d', '%s', '%s' )
		);

		if ( $update_status ) {

			wp_transition_post_status( $status, $from_status, get_post( $post_id ) );
			return true;

		}
	}
	return false;
}

/**
 * Shuffle assocciative array
 *
 * @param  array &$array
 * @return boolean
 */
function giveasap_shuffle_assoc( &$array ) {
	$keys = array_keys( $array );

	shuffle( $keys );

	foreach ( $keys as $key ) {
		$new[ $key ] = $array[ $key ];
	}

	$array = $new;

	return true;
}

/**
 * Return if Activation Required
 *
 * @since 2.11.0
 */
function giveasap_is_activation_required() {

	// Adding a check before accessing settings.
	$check = apply_filters( 'giveasap_is_activation_required', null );

	if ( null !== $check ) {
		return (bool) $check;
	}

	$settings = giveasap_get_settings();

	return isset( $settings['activation_required'] ) ? (bool) $settings['activation_required'] : false;
}

/**
 * Return if Email Login enabled
 *
 * @since 2.29.0
 *
 * @return boolean
 */
function giveasap_is_email_login_enabled() {

	// Adding a check before accessing settings.
	$check = apply_filters( 'giveasap_is_email_login_enabled', null );

	if ( null !== $check ) {
		return (bool) $check;
	}

	$settings = giveasap_get_settings();

	return isset( $settings['enable_email_login'] ) ? (bool) $settings['enable_email_login'] : false;
}

/**
 * Return if we should clone subscribers as well.
 *
 * @since 2.31.0
 *
 * @return bool
 */
function giveasap_is_cloning_subscribers_enabled() {

	$settings = giveasap_get_settings();

	return isset( $settings['clone_subscribers'] ) ? (bool) $settings['clone_subscribers'] : false;
}


/**
 * Return if we collect IP Addresses
 *
 * @since 2.31.0
 *
 * @return bool
 */
function giveasap_is_ip_enabled() {

	$settings = giveasap_get_settings();

	return isset( $settings['collect_ip_address'] ) ? (bool) $settings['collect_ip_address'] : false;
}

/**
 * Return if we should display from where the subscriber came from.
 *
 * @since 2.45.0
 *
 * @return bool
 */
function giveasap_show_visited_from() {

    $settings = giveasap_get_settings();

    return isset( $settings['show_visited_from'] ) ? (bool) $settings['show_visited_from'] : false;
}

/**
 * Get IP Address
 *
 * @since 2.31.0
 *
 * @return bool
 */
function giveasap_get_ip_address() {

	$ip = false;

	if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
		// ip from share internet.
		$ip = \Simple_Giveaways\Helpers::unslash_and_clean( $_SERVER['HTTP_CLIENT_IP'] );
	} elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
		// ip pass from proxy.
		$ip = \Simple_Giveaways\Helpers::unslash_and_clean( $_SERVER['HTTP_X_FORWARDED_FOR'] );
	} else {
		$ip = ! empty( $_SERVER['REMOTE_ADDR'] ) ? \Simple_Giveaways\Helpers::unslash_and_clean( $_SERVER['REMOTE_ADDR'] ) : false;
	}
	return $ip;

}

/**
 * Register User in a giveaway
 *
 * @param integer $giveaway_id The Giveaway ID (post ID)
 * @param string  $email Email entry
 * @param integer $entry Entries
 * @param string  $ref_id Reference ID (used for < 2.0.0 )
 * @param string  $user_status User Status.
 * @return mixed         Returns ID if successful, otherwise false
 */
function giveasap_register_user( $giveaway_id, $email, $entry = 1, $ref_id = '', $user_status = 'active' ) {
	global $wpdb;

	if ( giveasap_is_activation_required() && ! giveasap_is_user_already_active( $email ) ) {
		$user_status = 'pending';
	}

	$user_status = apply_filters( 'giveasap_register_user_status', $user_status, $giveaway_id, $email );

	$insert = $wpdb->insert(
		$wpdb->giveasap_entries,
		array(
			'post_id' => $giveaway_id,
			'email'   => $email,
			'entries' => $entry,
			'ref_id'  => $ref_id,
			'date'    => current_time( 'mysql' ),
			'status'  => $user_status,
		),
		array(
			'%d',
			'%s',
			'%d',
			'%s',
			'%s',
			'%s',
		)
	);

	if ( $insert ) {

		$ret = $wpdb->insert_id;

		do_action( 'giveasap_register_user', $wpdb->insert_id, $giveaway_id, $email, $entry, $ref_id );

		return $ret;
	}

	return $insert;
}

/**
 * Updating the User entry value
 *
 * @param  integer $user_id The ID of the registered user
 * @param  integer $entry   Value
 * @return boolean
 */
function giveasap_update_user_entry( $user_id, $entry ) {
	global $wpdb;
	$update = $wpdb->update(
		$wpdb->giveasap_entries,
		array(
			'entries' => $entry,
		),
		array( 'id' => $user_id ),
		array(
			'%d',   // value1
		),
		array( '%d' )
	);

	if ( false !== $update ) {

		do_action( 'giveasap_update_user_entry', $user_id, $entry );

		return true;
	}

	return false;
}

/**
 * Get the number of subscribers
 *
 * @param  integer $giveaway_id
 * @return integer
 */
function giveasap_get_subscribed_count( $giveaway_id ) {
	global $wpdb;

	$results = $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM ' . $wpdb->giveasap_entries . ' WHERE post_id = %d', $giveaway_id ) );

	$count = null !== $results ? $results : 0;
	return $count;
}

/**
 * Get all entries based on various filters
 *
 * @since 2.13.0
 *
 * @param  array $args
 * @return array
 */
function giveasap_query_giveaways( $args = array() ) {
	global $wpdb;

	$args = wp_parse_args(
		$args,
		array(
			'post_id'          => '',
			'orderby'          => 'id',
			'order'            => 'DESC',
			'status'           => 'publish',
			'limit'            => 10,
			'giveaways_not_in' => array(),
		)
	);

	$query = 'SELECT * FROM ' . $wpdb->giveasap_entries . ' as entries ';

	if ( $args['status'] ) {
		$query .= 'LEFT JOIN ' . $wpdb->posts . ' as posts on posts.ID = entries.post_id';
	}

	$query .= ' WHERE 1=1';

	if ( isset( $args['post_id'] ) && $args['post_id'] ) {
		$query .= $wpdb->prepare( ' AND post_id = %d ', absint( $args['post_id'] ) );
	}

	if ( $args['status'] ) {
		$query .= $wpdb->prepare( ' AND posts.post_status = %s ', $args['status'] );
	}

	if ( $args['giveaways_not_in'] ) {
		$query .= ' AND posts.post_id NOT IN ( ' . implode( ',', array_map( 'absint', $args['giveaways_not_in'] ) ) . ' )';
	}

	if ( $args['orderby'] && $args['order'] ) {
		$query .= $wpdb->prepare( ' ORDER BY %s ' . $args['order'], $args['orderby'] );
	}

	if ( $args['limit'] ) {
		$query .= $wpdb->prepare( ' LIMIT %d', absint( $args['limit'] ) );
	}

	$results = $wpdb->get_results( $query );

	return $results;
}

/**
 * Get all the entries from a Giveaway
 *
 * @param  integer $giveaway_id
 * @return array
 */
function giveasap_get_entries_for( $giveaway_id ) {
	global $wpdb;

	$results = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->giveasap_entries . ' WHERE post_id = %d', $giveaway_id ) );

	return $results;
}

/**
 * Get all the entries from a Giveaway
 *
 * @since 2.11.0
 *
 * @param  integer $giveaway_id
 * @param  integer $limit Since 2.25.0
 * @param  string  $order Since 2.25.0
 * @param  string  $orderby Since 2.25.0
 * @return array
 */
function giveasap_get_active_entries_for( $giveaway_id, $limit = null, $order = null, $orderby = null ) {
	global $wpdb;

	$sql = $wpdb->prepare( 'SELECT * FROM ' . $wpdb->giveasap_entries . ' WHERE post_id = %d AND status=%s', $giveaway_id, 'active' );

	$allowed_order = ['ASC', 'DESC'];
	$allowed_orderby = [
		'id',
		'post_id',
		'status',
		'email',
		'entries',
		'ref_id',
		'active',
		'date',
	];

	if (
		null !== $order &&
		in_array( strtoupper( $order ), $allowed_order, true ) &&
		null !== $orderby &&
		in_array( $orderby, $allowed_orderby, true )
	) {
		$sql .= " ORDER BY $orderby $order";
	}

	if ( null !== $limit ) {
		$sql .= $wpdb->prepare( ' LIMIT %d', $limit );
	}

	$results = $wpdb->get_results( $sql );

	return $results;
}

/**
 * Find and return the user
 *
 * @param  string $id Reference ID
 * @param  number $post_id Giveaway ID
 * @return array
 */
function giveasap_get_user( $id, $post_id ) {
	global $wpdb;

	$user = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->giveasap_entries . ' WHERE post_id = %d AND ( ref_id = %s )', $post_id, $id ) );

	return $user;
}

/**
 * Find and return the user
 *
 * @param  string $id Entry ID
 * @param  number $post_id Giveaway ID
 * @return object
 */
function giveasap_get_user_by_id( $id, $post_id = 0 ) {
	global $wpdb;

	$sql = $wpdb->prepare( 'SELECT * FROM ' . $wpdb->giveasap_entries . ' WHERE id = %d', $id );
	if ( $post_id ) {
		$sql .= ' AND post_id = %d';
		$sql  = $wpdb->prepare( $sql, $post_id );
	}
	$user = $wpdb->get_row( $sql );

	return $user;
}

/**
 * Find and return the user
 *
 * @param  string $email Email
 * @param  number $post_id Giveaway ID
 * @return object
 */
function giveasap_get_user_by_email( $email, $post_id ) {
	global $wpdb;

	$user = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->giveasap_entries . ' WHERE post_id = %d AND email = %s', $post_id, $email ) );

	return $user;
}

/**
 * Return if the email is blocked on a giveaway
 *
 * @since 2.35.0
 *
 * @param  string $email Email
 * @return bool
 */
function giveasap_is_email_blocked( $email ) {
	global $wpdb;

	$count = $wpdb->get_var( $wpdb->prepare( 'SELECT count(*) FROM ' . $wpdb->giveasap_entries . ' WHERE email = %s AND status = %s', $email, 'blocked' ) );

	return absint( $count ) > 0;
}

/**
 * Find the user by email
 *
 * @param  string $email
 * @param  number $post_id Giveaway ID
 * @return bool
 */
function giveasap_user_exists( $email, $post_id = false ) {
	global $wpdb;

	$sql = $wpdb->prepare( 'SELECT * FROM ' . $wpdb->giveasap_entries . ' WHERE email = %s', $email );

	if ( false !== $post_id ) {
		$sql .= $wpdb->prepare( ' AND post_id = %d', $post_id );
	}

	$user = $wpdb->get_row( $sql );

	if ( null === $user ) {
		return false;
	}

	return true;
}

/**
 * Find if the user is already active by email
 *
 * @param  string $email
 * @return bool
 */
function giveasap_is_user_already_active( $email ) {
	global $wpdb;

	$sql = $wpdb->prepare( 'SELECT * FROM ' . $wpdb->giveasap_entries . ' WHERE email = %s AND status=%s', $email, 'active' );

	$user = $wpdb->get_row( $sql );

	if ( null === $user ) {
		return false;
	}

	return true;
}

/**
 * Check if a Ref ID exists
 *
 * @param  string $id
 * @param  number $post_id
 * @return bool
 */
function giveasap_ref_id_exists( $id, $post_id ) {

	$exists = giveasap_get_user( $id, $post_id );

	if ( null === $exists ) {
		return false;
	}

	return true;
}

/**
 * Helper function for creating a unique ID
 *
 * @return string
 */
function giveasap_create_unique_id( $post_id ) {
	$id = md5( uniqid() );

	if ( giveasap_ref_id_exists( $id, $post_id ) ) {
		$id = giveasap_create_unique_id( $post_id );
	}

	return $id;
}

/**
 * Get WordPress Date format into JavaScript
 *
 * @return string
 */
function giveasap_get_JS_date_format( $format = '' ) {
	$date_format = ( '' === $format ) ? get_option( 'date_format' ) : $format;
	$date_format = str_replace( 'd', 'dd', $date_format );
	$date_format = str_replace( 'j', 'd', $date_format );
	$date_format = str_replace( 'Y', 'yy', $date_format );
	$date_format = str_replace( 'm', 'mm', $date_format );
	return $date_format;
}

/**
 * Get the Giveaway settings
 *
 * @since  2.4.0
 * @return array
 */
function giveasap_get_settings() {
	$gp = gasap();
	return $gp->get_settings();
}

/**
 * Return the Integrations
 *
 * @since  2.6.0
 * @return array
 */
function giveasap_get_integrations() {
	return apply_filters( 'giveasap_integrations', array() );
}

/**
 * Integration Categories
 *
 * @return mixed|void
 */
function giveasap_get_integration_categories() {
	return apply_filters(
		'giveasap_get_integration_classes',
		array(
			'automation'   => __( 'Automation', 'giveasap' ),
			'social'       => __( 'Social', 'giveasap' ),
			'ecommerce'    => __( 'eCommerce', 'giveasap' ),
			'marketing'    => __( 'Marketing', 'giveasap' ),
			'email'        => __( 'Email', 'giveasap' ),
			'gamification' => __( 'Gamification', 'giveasap' ),
		)
	);
}

/**
 * Setting the referrer for a subscribed user.
 *
 * @since 2.9.0
 *
 * @param integer $subscriber_id The Subscribed ID.
 * @param integer $ref_id        Referrer ID.
 */
function giveasap_set_referrer( $subscriber_id, $ref_id ) {
	giveasap_update_meta( $subscriber_id, '_referred_by', $ref_id );
}

/**
 * Get the referrer for a subscribed user.
 *
 * @since 2.9.0
 *
 * @param integer $subscriber_id The Subscribed ID.
 * @return integer|null
 */
function giveasap_get_referrer( $subscriber_id ) {
	return giveasap_get_meta( $subscriber_id, '_referred_by', true );
}

/**
 * Entry.
 *
 * @param integer|object $entry Entry ID or the Entry Object.
 * @param integer        $giveaway_id Giveaway ID.
 *
 * @return SG_Subscriber
 */
function giveasap_get_subscriber( $entry, $giveaway_id = 0 ) {
	return new SG_Subscriber( $entry, $giveaway_id );
}

/**
 * Delete the transient used in the leaderboard shotcode
 *
 * @param $giveaway_id
 */
function giveasap_delete_leaderboard_transient( $giveaway_id ) {
	delete_transient( 'giveaway_leaderboard_' . $giveaway_id );
}

/**
 * Reset the transient when updating the giveaway.
 */
function giveasap_reset_giveaway_leaderboard_transient_on_save( $post_id, $post ) {
	if ( 'giveasap' !== get_post_type( $post ) ) {
		return;
	}

	giveasap_delete_leaderboard_transient( $post_id );
}

/**
 * @param SG_Giveaway|integer $giveaway
 *
 * @return string
 */
function giveasap_get_rules_text( $giveaway ) {

	if ( is_numeric( $giveaway ) ) {
		$giveaway = giveasap_get_giveaway( $giveaway );
	}

	$text  = $giveaway->get_text_settings();
	$rules = ! empty( $text['rules_text'] ) ? $text['rules_text'] : '';

	if ( ! $rules ) {
		return '';
	}

	$sponsor_name      = ! empty( $text['rules_sponsor'] ) ? $text['rules_sponsor'] : '';
	$sponsor_address   = ! empty( $text['rules_sponsor_address'] ) ? $text['rules_sponsor_address'] : '';
	$sponsor_email     = ! empty( $text['rules_sponsor_email'] ) ? $text['rules_sponsor_email'] : '';
	$sponsor_country   = ! empty( $text['rules_sponsor_country'] ) ? $text['rules_sponsor_country'] : '';
	$sponsor_locations = ! empty( $text['rules_eligible_locations'] ) ? $text['rules_eligible_locations'] : '';
	$sponsor_age       = ! empty( $text['eligible_min_age'] ) ? $text['eligible_min_age'] : '';
	$giveaway_name     = $giveaway->get_post()->post_title;
	$giveaway_url      = giveasap_get_current_page_url();
	$date_format       = get_option( 'date_format', 'Y-m-d' );
	$start_date        = date_i18n( $date_format, $giveaway->get_schedule()->get_start_timestamp() );
	$end_date          = date_i18n( $date_format, $giveaway->get_schedule()->get_end_timestamp() );

	$placeholders = array(
		'sponsor_name'       => $sponsor_name,
		'sponsor_address'    => $sponsor_address,
		'sponsor_email'      => $sponsor_email,
		'sponsor_country'    => $sponsor_country,
		'eligible_locations' => $sponsor_locations,
		'eligible_min_age'   => $sponsor_age,
		'giveaway_name'      => $giveaway_name,
		'giveaway_url'       => $giveaway_url,
		'start_date'         => $start_date,
		'end_date'           => $end_date,
	);

	foreach ( $placeholders as $placeholder => $value ) {
		$rules = str_replace( '{{' . $placeholder . '}}', $value, $rules );
	}

	return $rules;
}

/**
 * Is email allowed for Giveaways.
 *
 * @param string $email Email string.
 *
 * @return bool
 */
function giveasap_is_email_allowed( $email ) {
	if ( ! $email ) {
		return false;
	}

	$email_parts = explode( '@', $email );
	$domain      = $email_parts[1];
	$settings    = giveasap_get_settings();

	$allowed_domains = isset( $settings['allowed_email_domains'] ) ? $settings['allowed_email_domains'] : '';

	if ( $allowed_domains ) {
		$allowed_domains = array_map( 'trim', explode( ',', $allowed_domains ) );
		return in_array( $domain, $allowed_domains, true );
	}

	$blocked_domains = isset( $settings['blocked_email_domains'] ) ? $settings['blocked_email_domains'] : '';
	if ( $blocked_domains ) {
		$blocked_domains = array_map( 'trim', explode( ',', $blocked_domains ) );
		return ! in_array( $domain, $blocked_domains, true );
	}

	return true;
}

/**
 * Retrieves unvalidated referer from '_wp_http_referer' or HTTP referer.
 *
 * Do not use for redirects, use {@see wp_get_referer()} instead.
 *
 * Copied from WooCommerce.
 *
 * @since 2.45.0
 * @return string|false Referer URL on success, false on failure.
 */
function giveasap_get_raw_referer() {
    if ( function_exists( 'wp_get_raw_referer' ) ) {
        return wp_get_raw_referer();
    }

    if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) { // WPCS: input var ok, CSRF ok.
        return wp_unslash( $_REQUEST['_wp_http_referer'] ); // WPCS: input var ok, CSRF ok, sanitization ok.
    } elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) ) { // WPCS: input var ok, CSRF ok.
        return wp_unslash( $_SERVER['HTTP_REFERER'] ); // WPCS: input var ok, CSRF ok, sanitization ok.
    }

    return false;
}