# datafeedr-api/1.0.124/functions/functions.php

Datafeedr API, version 1.0.124. 1,143 lines.

- Page: https://pluginprobe.com/plugins/datafeedr-api/1.0.124/code/functions/functions.php
- Raw: https://pluginprobe.com/plugins/datafeedr-api/1.0.124/raw/functions/functions.php
- Modified: 2020-12-28T15:03:48+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/datafeedr-api/1.0.124/code/functions/functions.php#L10-L20`.

```php
<?php

function dfrapi_get_api_usage_percentage() {
	$account = get_option( 'dfrapi_account' );
	if ( $account ) {
		if ( $account['max_requests'] > 0 ) {
			$percentage = floor ( ( intval( $account['request_count'] ) / intval( $account['max_requests'] ) * 100 ) );
		} else {
			$percentage = 0;
		}
		return $percentage;
	}
	return false;
}

add_action( 'init', 'dfrapi_email_user_about_usage' );
function dfrapi_email_user_about_usage() {

	$percentage = dfrapi_get_api_usage_percentage();
	$status = get_option( 'dfrapi_account', array() );

	$request_count = ( isset( $status['request_count'] ) ) ? abs( $status['request_count'] ) : 0;
	$remaining_requests = ( isset( $status['max_requests'] ) ) ? abs( $status['max_requests'] - $request_count ) : 0;

	$reset_date = '';
	if ( isset( $status['bill_day'] ) ) {
		$today = date('j');
		$num_days = date('t');
		if ( $status['bill_day'] > $num_days ) {
			$bill_day = $num_days;
		} else {
			$bill_day = $status['bill_day'];
		}
		if ( $bill_day == 0 ) {
			$reset_date .= '<em>' . __( 'Never', DFRAPI_DOMAIN ) . '</em>';
		} elseif ( $today >= $bill_day ) {
			$reset_date .= date('F', strtotime('+1 month')) . ' ' . $bill_day . ', ' . date('Y', strtotime('+1 month'));
		} else {
			$reset_date .= date('F') . ' ' . $bill_day . ', ' . date('Y');
		}
	}

	$default = array(
		'90_percent'  => '',
		'100_percent' => ''
	);

	// Don't do anything if less than 90%.
	if ( $percentage < 90 ) {
		update_option( 'dfrapi_usage_notification_tracker', $default );
		return;
	}

	$tracker = get_option( 'dfrapi_usage_notification_tracker', $default );

	$params 			= array();
	$params['to'] 		= get_bloginfo( 'admin_email' );
	$params['message']  = "<p>" . __( "This is an automated message generated by: ", DFRAPI_DOMAIN ) . get_bloginfo( 'wpurl' ) . "</p>";

	if ( $percentage >= 100 && empty( $tracker['100_percent'] ) ) {

		$params['subject']  = get_bloginfo( 'name' ) . __( ': Datafeedr API Usage (Critical)', DFRAPI_DOMAIN );

		$params['message'] .= "<p>" . __( "You have used <strong>100%</strong> of your allocated Datafeedr API requests for this period. <u>You are no longer able to query the Datafeedr API to get product information.</u>", DFRAPI_DOMAIN ) . "</p>";
		$params['message'] .= "<p><strong>" . __( "What to do next?", DFRAPI_DOMAIN ) . "</strong></p>";
		$params['message'] .= "<p>" . __( "We strongly recommend that you upgrade to prevent your product information from becoming outdated.", DFRAPI_DOMAIN ) . "</p>";
		$params['message'] .= "<p><a href=\"" . dfrapi_user_pages( 'change' ) . "?utm_source=email&utm_medium=link&utm_campaign=upgrade100percentnotice\"><strong>" . __( "UPGRADE NOW", DFRAPI_DOMAIN ) . "</strong></a></p>";
		$params['message'] .= "<p>" . __( "Upgrading only takes a minute. You will have <strong>instant access</strong> to more API requests. Any remaining credit for your current plan will be applied to your new plan.", DFRAPI_DOMAIN ) . "</p>";
		$params['message'] .= "<p>" . __( "You are under no obligation to upgrade. You may continue using your current plan for as long as you would like.", DFRAPI_DOMAIN ) . "</p>";
		$params['message'] .= "<p>" . __( "If you have any questions about your account, please ", DFRAPI_DOMAIN );
		$params['message'] .= "<a href=\"" . DFRAPI_EMAIL_US_URL . "?utm_source=email&utm_medium=link&utm_campaign=upgrade100percentnotice\">" . __( "contact us", DFRAPI_DOMAIN ) . "</a>.</p>";
		$params['message'] .= "<p>" . __( "Thanks,<br />Eric &amp; Stefan<br />The Datafeedr Team", DFRAPI_DOMAIN ) . "</p>";
		$params['message'] .= "<p>";
		$params['message'] .= "<a href=\"" . admin_url( 'admin.php?page=dfrapi_account' ) . "\">" . __( "Account Information", DFRAPI_DOMAIN ) . "</a> | ";
		$params['message'] .= "<a href=\"" . dfrapi_user_pages( 'change' ) . "?utm_source=email&utm_medium=link&utm_campaign=upgrade100percentnotice\">" . __( "Upgrade Account", DFRAPI_DOMAIN ) . "</a>";
		$params['message'] .= "</p>";

		$tracker['100_percent'] = 1;
		update_option( 'dfrapi_usage_notification_tracker', $tracker );

		add_filter( 'wp_mail_content_type', 'dfrapi_set_html_content_type' );
		wp_mail( $params['to'], $params['subject'], $params['message'] );
		remove_filter( 'wp_mail_content_type', 'dfrapi_set_html_content_type' );


	} elseif ( $percentage >= 90 && $percentage < 100 && empty( $tracker['90_percent'] ) ) {

		$params['subject']  = get_bloginfo( 'name' ) . __( ': Datafeedr API Usage (Warning)', DFRAPI_DOMAIN );
		$params['message'] .= "<p>" . __( "You have used <strong>90%</strong> of your allocated Datafeedr API requests for this period.", DFRAPI_DOMAIN ) . "</p>";
		$params['message'] .= "<p><strong>" . __( "API Usage", DFRAPI_DOMAIN ) . "</strong></p>";
		$params['message'] .= "<ul>";
		$params['message'] .= "<li>" . __( "API requests used: ", DFRAPI_DOMAIN ) . $request_count . "</li>";
		$params['message'] .= "<li>" . __( "API requests remaining: ", DFRAPI_DOMAIN ) . $remaining_requests . "</li>";
		$params['message'] .= "<li>" . __( "API requests will reset on: ", DFRAPI_DOMAIN ) . $reset_date . "</li>";
		$params['message'] .= "</ul>";
		$params['message'] .= "<p><strong>" . __( "What to do next?", DFRAPI_DOMAIN ) . "</strong></p>";
		$params['message'] .= "<p>" . __( "We recommend that you upgrade to prevent your product information from becoming outdated.", DFRAPI_DOMAIN ) . "</p>";
		$params['message'] .= "<p><a href=\"" . dfrapi_user_pages( 'change' ) . "?utm_source=email&utm_medium=link&utm_campaign=upgrade90percentnotice\"><strong>" . __( "UPGRADE NOW", DFRAPI_DOMAIN ) . "</strong></a></p>";
		$params['message'] .= "<p>" . __( "Upgrading only takes a minute. You will have <strong>instant access</strong> to more API requests. Any remaining credit for your current plan will be applied to your new plan.", DFRAPI_DOMAIN ) . "</p>";
		$params['message'] .= "<p>" . __( "You are under no obligation to upgrade. You may continue using your current plan for as long as you would like.", DFRAPI_DOMAIN ) . "</p>";
		$params['message'] .= "<p>" . __( "If you have any questions about your account, please ", DFRAPI_DOMAIN );
		$params['message'] .= "<a href=\"" . DFRAPI_EMAIL_US_URL . "?utm_source=email&utm_medium=link&utm_campaign=upgrade90percentnotice\">" . __( "contact us", DFRAPI_DOMAIN ) . "</a>.</p>";
		$params['message'] .= "<p>" . __( "Thanks,<br />Eric &amp; Stefan<br />The Datafeedr Team", DFRAPI_DOMAIN ) . "</p>";
		$params['message'] .= "<p>";
		$params['message'] .= "<a href=\"" . admin_url( 'admin.php?page=dfrapi_account' ) . "\">" . __( "Account Information", DFRAPI_DOMAIN ) . "</a> | ";
		$params['message'] .= "<a href=\"" . dfrapi_user_pages( 'change' ) . "?utm_source=email&utm_medium=link&utm_campaign=upgrade90percentnotice\">" . __( "Upgrade Account", DFRAPI_DOMAIN ) . "</a>";
		$params['message'] .= "</p>";

		$tracker['90_percent'] = 1;
		update_option( 'dfrapi_usage_notification_tracker', $tracker );

		add_filter( 'wp_mail_content_type', 'dfrapi_set_html_content_type' );
		wp_mail( $params['to'], $params['subject'], $params['message'] );
		remove_filter( 'wp_mail_content_type', 'dfrapi_set_html_content_type' );

	}

	return;
}

function dfrapi_set_html_content_type() {
	return 'text/html';
}

/**
 * Modify affiliate ID if product is a Zanox product.
 * Replaces $affiliate_id with "zmid".
 */
add_filter( 'dfrapi_affiliate_id', 'dfrapi_get_zanox_zmid', 10, 3 );
function dfrapi_get_zanox_zmid( $affiliate_id, $product, $networks ) {
	if ( isset( $product['source'] ) && preg_match( "/\bZanox\b/", $product['source'] ) ) {
		$zanox = dfrapi_api_get_zanox_zmid( $product['merchant_id'], $affiliate_id );
		$affiliate_id = ( !isset( $zanox[0]['zmid']) ) ? '___MISSING___' : $zanox[0]['zmid'];
	}
	return $affiliate_id;
}

/**
 * Modify affiliate ID if product is a Partnerize product.
 * Replaces $affiliate_id with "camref".
 *
 * @since 1.0.66
 *
 * @return string Affiliate ID.
 */
add_filter( 'dfrapi_affiliate_id', 'dfrapi_get_ph_camref', 10, 3 );
function dfrapi_get_ph_camref( $affiliate_id, $product, $networks ) {
	if ( isset( $product['source'] ) && preg_match( "/\bPartnerize\b/", $product['source'] ) ) {
		$ph           = dfrapi_api_get_ph_camref( $product['merchant_id'] );
		$affiliate_id = ( ! isset( $ph[0]['camref'] ) ) ? '___MISSING___' : $ph[0]['camref'];
	}

	return $affiliate_id;
}

/**
 * Modify affiliate ID if product is a Effiliation product.
 * Replaces $affiliate_id with "affiliate ID".
 *
 * @return string Affiliate ID.
 * @since 1.0.81
 *
 */
function dfrapi_get_effiliation_affiliate_id( $affiliate_id, $product, $networks ) {
	if ( isset( $product['source'] ) && preg_match( "/\bEffiliation\b/", $product['source'] ) ) {
		$effiliation  = dfrapi_api_get_effiliation_affiliate_id( $product['merchant_id'] );
		$affiliate_id = $effiliation == 'dfrapi_unapproved_effiliation_merchant' ? '___MISSING___' : $effiliation;
	}

	return $affiliate_id;
}

add_filter( 'dfrapi_affiliate_id', 'dfrapi_get_effiliation_affiliate_id', 10, 3 );

function dfrapi_get_zanox_keys() {

	$configuration = (array) get_option( 'dfrapi_configuration' );

	$zanox_connection_key = false;
	$zanox_secret_key = false;

	if ( isset( $configuration['zanox_connection_key'] ) && ( $configuration['zanox_connection_key'] != '' ) ) {
		$zanox_connection_key = $configuration['zanox_connection_key'];
	}

	if ( isset( $configuration['zanox_secret_key'] ) && ( $configuration['zanox_secret_key'] != '' ) ) {
		$zanox_secret_key = $configuration['zanox_secret_key'];
	}

	if ( $zanox_connection_key && $zanox_secret_key ) {
		return array(
			'connection_key'=> $zanox_connection_key,
			'secret_key' 	=> $zanox_secret_key,
		);
	}

	return false;
}

/**
 * Get Partnerize Keys.
 *
 * @since 1.0.66
 *
 * @return array|bool Array of keys or false if they do not exist.
 */
function dfrapi_get_ph_keys() {

	$configuration = (array) get_option( 'dfrapi_configuration' );

	$ph_application_key = false;
	$ph_user_api_key    = false;
	$ph_publisher_id    = false;

	if ( isset( $configuration['ph_application_key'] ) && ( $configuration['ph_application_key'] != '' ) ) {
		$ph_application_key = $configuration['ph_application_key'];
	}

	if ( isset( $configuration['ph_user_api_key'] ) && ( $configuration['ph_user_api_key'] != '' ) ) {
		$ph_user_api_key = $configuration['ph_user_api_key'];
	}

	if ( isset( $configuration['ph_publisher_id'] ) && ( $configuration['ph_publisher_id'] != '' ) ) {
		$ph_publisher_id = $configuration['ph_publisher_id'];
	}

	if ( $ph_application_key && $ph_user_api_key && $ph_publisher_id ) {
		return array(
			'application_key' => $ph_application_key,
			'user_api_key'    => $ph_user_api_key,
			'publisher_id'    => $ph_publisher_id,
		);
	}

	return false;
}

/**
 * Get Effiliation Keys.
 *
 * @since 1.0.81
 *
 * @return array|bool Array of keys or false if they do not exist.
 */
function dfrapi_get_effiliation_keys() {

	$configuration = (array) get_option( 'dfrapi_configuration' );

	$effiliation_key = false;

	if ( isset( $configuration['effiliation_key'] ) && ( $configuration['effiliation_key'] != '' ) ) {
		$effiliation_key = $configuration['effiliation_key'];
	}

	if ( $effiliation_key ) {
		return array(
			'effiliation_key' => $effiliation_key,
		);
	}

	return false;
}


/**
 * Returns Amazon API key credentials if they exist.
 *
 * If the Amazon API keys such as the Access Key ID, Secret Access Key, Tracking ID and Locale all
 * exists, then this function returns them in array format. Otherwise it returns false.
 *
 * @since 1.0.33
 *
 * @return array|bool Returns array of values if all values exist, otherwise false.
 */
function dfrapi_get_amazon_keys() {

	$configuration = (array) get_option( 'dfrapi_configuration' );

	$amazon_access_key_id     = false;
	$amazon_secret_access_key = false;
	$amazon_tracking_id       = false;
	$amazon_locale            = false;

	if ( isset( $configuration['amazon_access_key_id'] ) && ( $configuration['amazon_access_key_id'] != '' ) ) {
		$amazon_access_key_id = $configuration['amazon_access_key_id'];
	}

	if ( isset( $configuration['amazon_secret_access_key'] ) && ( $configuration['amazon_secret_access_key'] != '' ) ) {
		$amazon_secret_access_key = $configuration['amazon_secret_access_key'];
	}

	if ( isset( $configuration['amazon_tracking_id'] ) && ( $configuration['amazon_tracking_id'] != '' ) ) {
		$amazon_tracking_id = $configuration['amazon_tracking_id'];
	}

	if ( isset( $configuration['amazon_locale'] ) && ( $configuration['amazon_locale'] != '' ) ) {
		$amazon_locale = $configuration['amazon_locale'];
	}

	if ( $amazon_access_key_id && $amazon_secret_access_key && $amazon_tracking_id && $amazon_locale ) {
		return array(
			'amazon_access_key_id'     => $amazon_access_key_id,
			'amazon_secret_access_key' => $amazon_secret_access_key,
			'amazon_tracking_id'       => $amazon_tracking_id,
			'amazon_locale'            => $amazon_locale,
		);
	}

	return false;
}

/**
 * Returns a link to a user page on v4.datafeedr.com.
 */
function dfrapi_user_pages( $page ) {

	$pages = array(
		'edit' 		=> 'https://members.datafeedr.com/account',
		'invoices' 	=> 'https://members.datafeedr.com/invoices',
		'billing' 	=> 'https://members.datafeedr.com/billing',
		'cancel' 	=> 'https://members.datafeedr.com/',
		'change' 	=> 'https://members.datafeedr.com/subscription',
		'signup' 	=> 'https://members.datafeedr.com/subscribe',
		'summary' 	=> 'https://members.datafeedr.com/subscription',
		'api' 	    => 'https://members.datafeedr.com/api',
		'factory' 	=> 'https://members.datafeedr.com/factory',
	);

	return $pages[$page];
}

/**
 * Adds option name to transient whitelist. This is so we know
 * all transient options that can be deleted when deleting the
 * API cache on Tools page.
 */
function dfrapi_update_transient_whitelist( $option_name ) {
	$whitelist = get_option( 'dfrapi_transient_whitelist', array() );
	$whitelist[] = $option_name;
	update_option( 'dfrapi_transient_whitelist', array_unique( $whitelist ) );
}

/**
 * Add affiliate ID and tracking ID to an affiliate link.
 *
 * @param array $product An array of a single Datafeedr $product.
 *
 * @return string A URL with affiliate ID inserted or an empty string if the affiliate ID is missing.
 */
function dfrapi_url( $product ) {

	// Get all the user's selected networks.
	$networks = (array) get_option( 'dfrapi_networks' );

	// Support added for Amazon in version 1.0.60 (2017-10-18) Ticket #15201
	if ( substr( $product['source'], 0, 6 ) === "Amazon" ) {
		// Get the user's Amazon Associate Tag
		$affiliate_id = dfrapi_get_amazon_associate_tag();
	} else {
		// Extract the affiliate ID from the $networks array.
		$affiliate_id = isset( $networks['ids'][ $product['source_id'] ]['aid'] ) ? $networks['ids'][ $product['source_id'] ]['aid'] : '';
	}

	$affiliate_id = apply_filters( 'dfrapi_affiliate_id', $affiliate_id, $product, $networks );
	$affiliate_id = trim( $affiliate_id );

	// Extract the Tracking ID from the $networks array.
	$tracking_id = ( isset( $networks['ids'][ $product['source_id'] ]['tid'] ) ) ? $networks['ids'][ $product['source_id'] ]['tid'] : '';
	$tracking_id = apply_filters( 'dfrapi_tracking_id', $tracking_id, $product, $networks );
	$tracking_id = trim( $tracking_id );

	// Affiliate ID is missing.  Do action and return empty string.
	if ( $affiliate_id == '' ) {
		do_action( 'dfrapi_affiliate_id_is_missing', $product );

		return '';
	}

	// Determine which URL field to get: 'url' OR 'ref_url'. Return 'url' if $tracking_id is empty, otherwise, use 'ref_url'.
	$url = ( $tracking_id !== '' && isset( $product['ref_url'] ) ) ? $product['ref_url'] : $product['url'];

	// Apply filters to URL before affiliate & tracking ID insertion.
	$url = apply_filters( 'dfrapi_before_affiliate_id_insertion', $url, $product, $affiliate_id );
	$url = apply_filters( 'dfrapi_before_tracking_id_insertion', $url, $product, $tracking_id );

	// Replace placeholders in URL.
	$placeholders = array( "@@@", "###" );
	$replacements = array( $affiliate_id, $tracking_id );
	$url          = str_replace( $placeholders, $replacements, $url );

	// Apply filters to URL after affiliate & tracking ID insertion.
	$url = apply_filters( 'dfrapi_after_affiliate_id_insertion', $url, $product, $affiliate_id );
	$url = apply_filters( 'dfrapi_after_tracking_id_insertion', $url, $product, $tracking_id );

	// Return URL
	return $url;
}

/**
 * Return Amazon Associate Tag (ie. Tracking ID).
 *
 * @since 1.0.60
 *
 * @return string Associate Tag or empty string if it does not exist.
 */
function dfrapi_get_amazon_associate_tag() {
	$config = get_option( 'dfrapi_configuration' );

	return ( isset( $config['amazon_tracking_id'] ) ) ? $config['amazon_tracking_id'] : '';
}

/**
 * Add affiliate ID to impression URL.
 *
 * Since 1.0.39
 *
 * @param $product - An array of a single's product's information.
 */
function dfrapi_impression_url( $product ) {

	$impression_url = ( isset( $product['impressionurl'] ) ) ? trim( $product['impressionurl'] ) : false;

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

	// Get all the user's selected networks.
	$networks = (array) get_option( 'dfrapi_networks' );

	// Extract the affiliate ID from the $networks array.
	$affiliate_id = $networks['ids'][ $product['source_id'] ]['aid'];
	$affiliate_id = apply_filters( 'dfrapi_affiliate_id', $affiliate_id, $product, $networks );
	$affiliate_id = trim( $affiliate_id );

	// Affiliate ID is missing.  Do action and return empty string.
	if ( $affiliate_id == '' ) {
		do_action( 'dfrapi_affiliate_id_is_missing_impression', $product );

		return '';
	}

	// Apply filters to URL before affiliate & tracking ID insertion.
	$impression_url = apply_filters( 'dfrapi_before_affiliate_id_insertion_impression', $impression_url, $product, $affiliate_id );

	// Replace placeholders in URL.
	$placeholders   = array( "@@@" );
	$replacements   = array( $affiliate_id );
	$impression_url = str_replace( $placeholders, $replacements, $impression_url );

	// Apply filters to URL after affiliate & tracking ID insertion.
	$impression_url = apply_filters( 'dfrapi_after_affiliate_id_insertion_impression', $impression_url, $product, $affiliate_id );

	// Return URL
	return $impression_url;
}

/**
 * Output an error message generated by the API.
 */
function dfrapi_output_api_error( $data ) {
	$error = @$data['dfrapi_api_error'];
	$params = @$data['dfrapi_api_error']['params'];
	?>
	<div class="dfrapi_api_error">
		<div class="dfrapi_head"><?php _e( 'Datafeedr API Error', DFRAPI_DOMAIN ); ?></div>
		<div class="dfrapi_msg"><strong><?php _e( 'Message:', DFRAPI_DOMAIN ); ?></strong> <?php echo $error['msg']; ?></div>
		<div class="dfrapi_code"><strong><?php _e( 'Code:', DFRAPI_DOMAIN ); ?></strong> <?php echo $error['code']; ?></div>
		<div class="dfrapi_class"><strong><?php _e( 'Class:', DFRAPI_DOMAIN ); ?></strong> <?php echo $error['class']; ?></div>
		<?php if ( is_array( $params ) ) : ?>
			<div class="dfrps_query"><strong><?php _e( 'Query:', DFRAPI_DOMAIN ); ?></strong> <span><?php echo dfrapi_display_api_request( $params ); ?></span></div>
		<?php endif; ?>
	</div>
	<?php
}

/**
 * Convert a currency code to sign. USD => $
 *
 * @https://github.com/pelle/bux/blob/master/src/bux/currencies.clj
 *
 * Currently supported currencies:
 *
 * AUD	Australia	&#36;
 * BRL	Brazil	R$
 * CAD	Canada	&#36;
 * CHF	Switzerland	Fr
 * DKK	Denmark	kr
 * EUR	Belgium	&euro;
 * EUR	Finland	&euro;
 * EUR	France	&euro;
 * EUR	Germany	&euro;
 * EUR	Ireland	&euro;
 * EUR	Italy	&euro;
 * EUR	Netherlands	&euro;
 * EUR	Spain	&euro;
 * GBP	United Kingdom	&pound;
 * HUF	Hungary	Fr
 * INR	India	&#8377;
 * MYR	Malaysia	RM
 * NOK	Norway	kr
 * NZD	New Zealand	&#36;
 * PHP  Philippines  &#8369;
 * PLN	Poland	zł
 * RON	Romania L
 * RUB	Russia	₽
 * SEK	Sweden	kr
 * TRY	Turkey	&#8356;
 * USD	United States	&#36;
 *
 */
function dfrapi_currency_code_to_sign( $code ) {

	$map = array(
		'AUD' => '&#36;',
		'BRL' => 'R$',
		'CAD' => '&#36;',
		'CHF' => 'Fr',
		'DKK' => 'kr',
		'EUR' => '&euro;',
		'GBP' => '&pound;',
		'HUF' => 'Ft',
		'INR' => '&#8377;',
		'MYR' => 'RM',
		'NOK' => 'kr',
		'NZD' => '&#36;',
		'PLN' => 'zł',
		'PHP' => '&#8369;',
		'RON' => 'L',
		'RUB' => '&#8381;',
		'SEK' => 'kr',
		'TRY' => '&#8356;',
		'USD' => '&#36;',
		'CZK' => '&#75;&#269;',
	);

	$map = apply_filters( 'dfrapi_currency_sign_mapper', $map );

	if ( isset ( $map[$code] ) ) {
		return $map[$code];
	} else {
		return $map['USD'];
	}
}

/**
 * This displays the API request in PHP format.
 */
function dfrapi_display_api_request( $params=array() ) {

	$html = '';

	if ( empty( $params ) ) { return $html; }

	$html .= '$search = $api->searchRequest();<br />';
	foreach ( $params as $k => $v ) {

		// Handle query.
		if ( $k == 'query' ) {
			foreach ( $v as $query ) {
				if ( substr( $query, 0, 9 ) !== 'source_id' || substr( $query, 0, 11 ) !== 'merchant_id' ) {
					$query = str_replace( ",", ", ", $query );
				}
				$html .= '$search->addFilter( \''.( $query ).'\' );<br />';
			}
		}

		// Handle sort.
		if ( $k == 'sort' ) {
			foreach ( $v as $sort ) {
				$html .= '$search->addSort( \''.stripslashes( $sort ).'\' );<br />';
			}
		}

		// Handle limit.
		if ( $k == 'limit' ) {
			$html .= '$search->setLimit( \''.stripslashes( $v ).'\' );<br />';
		}

		// Handle merchant_limit.
		if ( $k == 'merchant_limit' ) {
			$html .= '$search->setMerchantLimit( \''.stripslashes( absint($v) ).'\' );<br />';
		}

		// Handle Offset.
		if ( $k == 'offset' ) {
			$html .= '$search->setOffset( \''.stripslashes( $v ).'\' );<br />';
		}

		// Handle Exclude duplicates.
		if ( $k == 'exclude_duplicates' ) {
			$html .= '$search->excludeDuplicates( \''. $v  . '\' );<br />';
		}
	}

	$html .= '$products = $search->execute();';
	return $html;

}

function dfrapi_get_query_param( $query, $param ) {
	if ( is_array( $query ) && !empty( $query ) ) {
		foreach( $query as $k => $v ) {
			if ( $v['field'] == $param ) {
				return array(
					'field' 	=> @$v['field'],
					'operator' 	=> @$v['operator'],
					'value' 	=> @$v['value'],
				);
			}
		}
	}
	return false;
}

/**
 * Converts a value in cents into a value with proper
 * decimal placement.
 *
 * Example: 14999 => 149.99
 */
function dfrapi_int_to_price( $price ) {
	return number_format( ( $price/100 ), 2 );
}

/**
 * Converts decimal or none decimal prices into values in cents.
 *
 * assert(dfrapi_price_to_int('123')     		==12300);
 * assert(dfrapi_price_to_int('123.4')   		==12340);
 * assert(dfrapi_price_to_int('1234.56') 		==123456);
 * assert(dfrapi_price_to_int('123,4')   		==12340);
 * assert(dfrapi_price_to_int('1234,56') 		==123456);
 * assert(dfrapi_price_to_int('1,234,567')    	==123456700);
 * assert(dfrapi_price_to_int('1,234,567.8')  	==123456780);
 * assert(dfrapi_price_to_int('1,234,567.89') 	==123456789);
 * assert(dfrapi_price_to_int('1.234.567')    	==123456700);
 * assert(dfrapi_price_to_int('1.234.567,8')  	==123456780);
 * assert(dfrapi_price_to_int('1.234.567,89') 	==123456789);
 * assert(dfrapi_price_to_int('FOO 123 BAR')    ==12300);
 */
function dfrapi_price_to_int( $price ) {
    $d = $price;
    $d = preg_replace('~^[^\d.,]+~', '', $d);
    $d = preg_replace('~[^\d.,]+$~', '', $d);

    // 123 => 12300
    if(preg_match('~^(\d+)$~', $d, $m))
        return intval($m[1] . '00');

    // 123.4 => 12340, 123,45 => 12345
    if(preg_match('~^(\d+)[.,](\d{1,2})$~', $d, $m))
        return intval($m[1] . substr($m[2] . '0000', 0, 2));

    // 1,234,567.89 => 123456789
    if(preg_match('~^((?:\d{1,3})(?:,\d{3})*)(\.\d{1,2})?$~', $d, $m)) {
        $f = isset($m[2]) ? $m[2] : '.';
        return intval(str_replace(',', '', $m[1]) . substr($f . '0000', 1, 2));
    }

    // 1.234.567,89 => 123456789
    if(preg_match('~^((?:\d{1,3})(?:\.\d{3})*)(,\d{1,2})?$~', $d, $m)) {
        $f = isset($m[2]) ? $m[2] : '.';
        return intval(str_replace('.', '', $m[1]) . substr($f . '0000', 1, 2));
    }

    return NULL;
}

function dfrapi_html_output_api_error( $data ) {
	$error = $data['dfrapi_api_error'];
	$params = @$data['dfrapi_api_error']['params'];
	?>
	<div class="dfrapi_api_error">
		<div class="dfrapi_head"><?php _e( 'Datafeedr API Error', DFRAPI_DOMAIN ); ?></div>
		<div class="dfrapi_msg"><strong><?php _e( 'Message:', DFRAPI_DOMAIN ); ?></strong> <?php echo $error['msg']; ?></div>
		<div class="dfrapi_code"><strong><?php _e( 'Code:', DFRAPI_DOMAIN ); ?></strong> <?php echo $error['code']; ?></div>
		<div class="dfrapi_class"><strong><?php _e( 'Class:', DFRAPI_DOMAIN ); ?></strong> <?php echo $error['class']; ?></div>
		<?php if ( is_array( $params ) ) : ?>
			<div class="dfrapi_query"><strong><?php _e( 'Query:', DFRAPI_DOMAIN ); ?></strong> <span><?php echo dfrapi_helper_display_api_request( $params ); ?></span></div>
		<?php endif; ?>
	</div>
	<?php
}

function dfrapi_get_total_products_in_db( $formatted=TRUE, $default=0 ) {

	$account = get_option( 'dfrapi_account' );
	$product_count = $default;

	if ( $account ) {
		if ( isset( $account['product_count'] ) ) {
			$product_count = intval( $account['product_count'] );
		}
	}

	if ( $formatted && is_int( $product_count ) ) {
		$product_count = number_format( $product_count );
	}

	return $product_count;
}

/**
 * Imports an image from a URL into the WordPress Media Library.
 *
 * @since 1.0.71
 *
 * @param string $url Image URL.
 * @param array $args Optional. An array of options. See Datafeedr_Image_Importer::default_args()
 *
 * @return Datafeedr_Image_Importer
 */
function datafeedr_import_image( $url, $args = array() ) {
	return ( new Datafeedr_Image_Importer( $url, $args ) )->import();
}

/**
 * Returns true if the $string starts with one of the $patterns. Otherwise returns false.
 *
 * @since 1.0.78
 *
 * @param string $string The haystack.
 * @param string|array $patterns The patterns to search for in the beginning of the $string.
 *
 * @return bool True if string starts with the pattern(s) else returns false.
 */
function dfrapi_string_starts_with( $string, $patterns ) {
	$patterns = ( is_string( $patterns ) ) ? array( $patterns ) : $patterns;
	foreach ( $patterns as $pattern ) {
		$length = mb_strlen( $pattern );
		if ( mb_substr( $string, 0, $length ) === $pattern ) {
			return true;
		}
	}

	return false;
}

/**
 * Includes HelpScout Beacon if enabled and if on a Datafeedr-specific page.
 *
 * @since 1.0.84
 */
function dfrapi_include_helpscout_beacon() {

	$options = get_option( 'dfrapi_configuration', [] );

	if ( isset( $options['hs_beacon'] ) && 'off' == $options['hs_beacon'] ) {
		return;
	}

	if ( ! dfrapi_is_datafeedr_admin_page() ) {
		return;
	}

	include_once DFRAPI_PATH . 'js/helpscout-beacon.php';

	return;
}

add_action( 'admin_footer', 'dfrapi_include_helpscout_beacon' );

/**
 * Returns true if we are viewing a Datafeedr-specific page in the WordPress Admin Area.
 *
 * @global $pagenow
 *
 * @since 1.0.84
 *
 * @return bool
 */
function dfrapi_is_datafeedr_admin_page() {

	/**
	 * For post edit pages (ie. post.php?post=1&action=edit).
	 */
	$post_types = [
		'datafeedr-productset',
	];

	/**
	 * For $_GET params (ie. admin.php?page=dfrps_configuration).
	 */
	$params = [
		'page'      => [
			'dfrapi',
			'dfrapi_networks',
			'dfrapi_merchants',
			'dfrapi_tools',
			'dfrapi_export',
			'dfrapi_import',
			'dfrapi_account',
			'dfrcs_options',
			'dfrps_configuration',
			'dfrps_tools',
			'dfrpswc_options',
		],
		'post_type' => [
			'datafeedr-productset'
		]
	];

	foreach ( $params as $k => $v ) {
		if ( isset( $_GET[ $k ] ) && in_array( $_GET[ $k ], $v ) ) {
			return true;
		}
	}

	global $pagenow;

	if ( 'post.php' === $pagenow && in_array( get_post_type(), $post_types ) ) {
		return true;
	}

	return false;
}

/**
 * @param integer $network_id
 * @param string $id_type
 *
 * @return WP_Error|string
 */
function dfrapi_get_affiliate_and_tracking_id( $network_id, $id_type = 'aid' ) {

	static $networks = null;

	$key  = 'ids';
	$type = ( 'tid' == $id_type ) ? 'tid' : 'aid';

	if ( null === $networks ) {
		$networks = get_option( 'dfrapi_networks', [] );
	}

	if ( empty( $networks ) ) {
		return new WP_Error(
			'dfrapi_get_affiliate_id_no_networks',
			__( 'No networks selected.', 'datafeedr-api' )
		);
	}

	if ( ! isset( $networks[ $key ] ) ) {
		return new WP_Error(
			'dfrapi_get_affiliate_id_no_network_ids',
			__( 'No network IDs selected.', 'datafeedr-api' )
		);
	}

	if ( ! isset( $networks[ $key ][ $network_id ] ) ) {
		return new WP_Error(
			'dfrapi_get_affiliate_id_no_network_ids',
			__( 'No data for network with ID of ' . intval( $network_id ), 'datafeedr-api' )
		);
	}

	if ( ! isset( $networks[ $key ][ $network_id ][ $type ] ) || empty( $networks[ $key ][ $network_id ][ $type ] ) ) {
		return new WP_Error(
			'dfrapi_get_affiliate_id_empty_type',
			__( 'No affiliate or tracking ID entered for network with ID of ' . intval( $network_id ), 'datafeedr-api' )
		);
	}

	return $networks[ $key ][ $network_id ][ $type ];
}

/**
 * @param array $merchants
 * @param array $network
 *
 * @return array|WP_Error|null
 */
function dfrapi_remove_unapproved_awin_merchants( $merchants, $network ) {

	// Return if not in Awin network.
	if ( 10006 != $network['group_id'] ) {
		return $merchants;
	}

	$affiliate_id = dfrapi_get_affiliate_and_tracking_id( $network['_id'], 'aid' );

	if ( is_wp_error( $affiliate_id ) ) {
		return new WP_Error(
			'missing_awin_affiliate_id',
			'Please enter your Awin affiliate ID for ' . esc_html( $network['name'] ) . ' <a href="' . admin_url( 'admin.php?page=dfrapi_networks' ) . '#group_affiliatewindow" target="_blank">here</a>.'
		);
	}

	static $awin_access_token = null;

	if ( null === $awin_access_token ) {

		$config = get_option( 'dfrapi_configuration', [] );

		$awin_access_token = ( isset( $config['awin_access_token'] ) && ! empty( $config['awin_access_token'] ) ) ?
			trim( $config['awin_access_token'] ) :
			new WP_Error(
				'awin_access_token_missing',
				'Please enter your Awin API Token <a href="' . admin_url( 'admin.php?page=dfrapi' ) . '" target="_blank">here</a>.'
			);
	}

	if ( is_wp_error( $awin_access_token ) ) {
		return $awin_access_token;
	}

	$url                  = null;
	$approved_program_ids = null;

	$url = sprintf(
		'https://api.awin.com/publishers/%1$s/programmes?relationship=joined&accessToken=%2$s',
		$affiliate_id, $awin_access_token
	);

	$response = wp_remote_get( $url );

	if ( is_array( $response ) && ! is_wp_error( $response ) ) {
		if ( isset( $response['response']['code'] ) && '200' == $response['response']['code'] ) {
			if ( isset( $response['body'] ) ) {
				$programs             = json_decode( $response['body'], true );
				$approved_program_ids = wp_list_pluck( $programs, 'id' );
			}
		}
	}

	if ( null === $approved_program_ids ) {
		return new WP_Error(
			'unable_to_retrieve_approved_awin_program_ids',
			'Unable to get your list of joined ' . esc_html( $network['name'] ) . ' programs. Please ensure your Awin Access Token is correct <a href="' . admin_url( 'admin.php?page=dfrapi' ) . '" target="_blank">here</a> and your affiliate ID is correct <a href="' . admin_url( 'admin.php?page=dfrapi_networks' ) . '#group_affiliatewindow" target="_blank">here</a>.' );
	}

	foreach ( $merchants as $key => $merchant ) {

		$approved = false;
		$suids    = isset( $merchant['suids'] ) ? explode( ',', $merchant['suids'] ) : [];

		foreach ( $suids as $suid ) {
			if ( in_array( $suid, $approved_program_ids ) ) {
				$approved = true;
			}
		}

		if ( ! $approved ) {
			unset( $merchants[ $key ] );
		}
	}

	return $merchants;
}

add_filter( 'dfrapi_list_merchants', 'dfrapi_remove_unapproved_awin_merchants', 10, 2 );

/**
 * @param   array  $merchants
 * @param   array  $network
 *
 * @return array|WP_Error|null
 * @since 1.0.102
 */
function dfrapi_disable_affiliate_gateway_merchant_selection_when_sid_empty( $merchants, $network ) {

	// Return if not in The Affiliate Gateway network.
	if ( 10033 != $network['group_id'] ) {
		return $merchants;
	}

	$sid = dfrapi_get_affiliate_gateway_sid();

	if ( is_wp_error( $sid ) ) {
		return $sid;
	}

	return $merchants;
}

add_filter( 'dfrapi_list_merchants', 'dfrapi_disable_affiliate_gateway_merchant_selection_when_sid_empty', 10, 2 );

/**
 * Get The Affiliate Gateway SID from this page WordPress Admin Area > Datafeedr API > Configuration
 *
 * @return string|WP_Error
 * @since 1.0.102
 */
function dfrapi_get_affiliate_gateway_sid() {

	static $sid = null;

	if ( null === $sid ) {

		$config = get_option( 'dfrapi_configuration', [] );

		$sid = ( isset( $config['affiliate_gateway_sid'] ) && ! empty( $config['affiliate_gateway_sid'] ) ) ?
			trim( $config['affiliate_gateway_sid'] ) :
			new WP_Error(
				'missing_affiliate_gateway_sid',
				'Please enter your The Affiliate Gateway SID <a href="' . admin_url( 'admin.php?page=dfrapi' ) . '" target="_blank">here</a>.'
			);
	}

	return $sid;
}

/**
 * Insert SID into The Affiliate Gateway affiliate links.
 *
 * @param   string  $url
 * @param   array   $product
 * @param   string  $tracking_id
 *
 * @return string
 */
function dfrapi_insert_affiliate_gateway_sid_into_affiliate_link( $url, $product, $tracking_id ) {

	if ( $product['source'] != 'The Affiliate Gateway' ) {
		return $url;
	}

	$sid = dfrapi_get_affiliate_gateway_sid();

	if ( is_wp_error( $sid ) ) {
		return $url;
	}

	$url = str_replace( '{SID}', $sid, $url );

	return $url;
}

add_filter( 'dfrapi_after_tracking_id_insertion', 'dfrapi_insert_affiliate_gateway_sid_into_affiliate_link', 20, 3 );

/**
 * @param array $merchants
 * @param array $network
 *
 * @return array|WP_Error|null
 * @since 1.0.124
 */
function dfrapi_disable_belboon_merchant_selection_when_aid_empty( $merchants, $network ) {

	// Return if not in Belboon network.
	if ( 10007 != $network['group_id'] ) {
		return $merchants;
	}

	$aid = dfrapi_get_belboon_adspace_id();

	if ( is_wp_error( $aid ) ) {
		return $aid;
	}

	return $merchants;
}

add_filter( 'dfrapi_list_merchants', 'dfrapi_disable_belboon_merchant_selection_when_aid_empty', 10, 2 );

/**
 * Get Belboon Adspace ID from this page WordPress Admin Area > Datafeedr API > Configuration
 *
 * @return string|WP_Error
 * @since 1.0.124
 */
function dfrapi_get_belboon_adspace_id() {

	static $aid = null;

	if ( null === $aid ) {

		$config = get_option( 'dfrapi_configuration', [] );

		$aid = ( isset( $config['belboon_aid'] ) && ! empty( $config['belboon_aid'] ) ) ?
			trim( $config['belboon_aid'] ) :
			new WP_Error(
				'missing_belboon_aid',
				'Please enter your Belboon Adspace ID <a href="' . admin_url( 'admin.php?page=dfrapi' ) . '" target="_blank">here</a>.'
			);
	}

	return $aid;
}

/**
 * Insert Adspace ID into Belboon affiliate links.
 *
 * @param string $url
 * @param array $product
 * @param string $affiliate_id
 *
 * @return string
 * @since 1.0.124
 */
function dfrapi_insert_belboon_adspace_id_into_affiliate_link( $url, $product, $affiliate_id ) {

	if ( strpos( $product['source'], 'Belboon' ) === false ) {
		return $url;
	}

	$aid = dfrapi_get_belboon_adspace_id();

	if ( is_wp_error( $aid ) ) {
		return $url;
	}

	$url = str_replace( '{AID}', $aid, $url );

	return $url;
}

add_filter( 'dfrapi_before_affiliate_id_insertion', 'dfrapi_insert_belboon_adspace_id_into_affiliate_link', 20, 3 );

/**
 * @param string $url
 * @param string $method
 * @param array $args
 *
 * @return SimpleXMLElement|WP_Error
 */
function dfrapi_get_xml_response( $url, $method = 'GET', array $args = [] ) {

	$response = $method === 'GET' ? wp_remote_get( $url, $args ) : wp_remote_post( $url, $args );

	if ( is_wp_error( $response ) ) {
		return $response;
	}

	$code = wp_remote_retrieve_response_code( $response );
	$body = wp_remote_retrieve_body( $response );

	if ( $code < 200 || $code >= 300 ) {
		return new WP_Error( $code, strip_tags( $body ) );
	}

	if ( ! strlen( $body ) ) {
		return new WP_Error( 'connection_error', esc_html__( 'Empty response', 'datafeedr' ) );
	}

	$xml = simplexml_load_string( $body, null, LIBXML_NOCDATA );

	if ( $xml->getName() == 'error' ) {
		return new WP_Error( $code, esc_html( strval( $xml->message ) ) );
	}

	return $xml;
}

```
