PNG %k25u25%fgd5n!
<?php
/**
* File: ecre-functions.php
*
* This file contains functions for coupon code generation and management.
*
* @package ECRE
* @since 1.0.0
*/
$ecre_plugin_list = function_exists( 'get_option' ) ? \get_option( 'active_plugins' ) : array();
if ( function_exists( 'is_multisite' ) && is_multisite() && function_exists( 'get_site_option' ) ) {
$ecre_network_active_plugins = get_site_option( 'active_sitewide_plugins', array() );
$ecre_plugin_list = array_merge( $ecre_plugin_list, array_keys( $ecre_network_active_plugins ) );
}
if ( in_array( 'woocommerce/woocommerce.php', $ecre_plugin_list, true ) ) {
if ( ! function_exists( 'ecre_generate_unique_coupon_code' ) ) {
/**
* Generate a unique coupon code.
*
* Creates a random 13-character lowercase alphanumeric coupon code and ensures
* it is unique by checking against existing WooCommerce coupons. If a collision
* occurs, a new code is generated until a unique one is found.
*
* @since 1.0.0
*
* @return string The generated unique coupon code (13 characters, lowercase alphanumeric).
*/
function ecre_generate_unique_coupon_code() {
$code = strtolower( wp_generate_password( 8, false ) );
// Ensure uniqueness using WooCommerce function.
while ( wc_get_coupon_id_by_code( $code ) > 0 ) {
$code = strtolower( wp_generate_password( 8, false ) );
}
return $code;
}
}
if ( ! function_exists( 'ecre_coupon_exists' ) ) {
/**
* Check if a coupon with the given code exists.
*
* Checks the WooCommerce database to determine if a coupon with the specified
* code already exists in the system.
*
* @since 1.0.0
*
* @param string $code The coupon code to check.
*
* @return bool True if the coupon exists, false otherwise.
*/
function ecre_coupon_exists( $code ) {
return wc_get_coupon_id_by_code( $code ) > 0;
}
}
if ( ! function_exists( 'ecre_coupon_exists_old' ) ) {
/**
* Check if a coupon with the given code exists.
*
* @param string $code The coupon code to check.
*
* @return bool Whether a coupon with the given code exists.
*
* @since 1.0.0
*/
function ecre_coupon_exists_old( $code ) {
global $wpdb;
$coupon_id = $wpdb->get_var(
$wpdb->prepare(
"SELECT ID FROM {$wpdb->posts}
WHERE post_type = %s
AND post_title = %s
AND post_status IN ('publish', 'draft', 'pending', 'private')
LIMIT 1",
'shop_coupon',
$code
)
);
return ! empty( $coupon_id );
}
}
if ( ! function_exists( 'ecre_referral_coupons' ) ) {
/**
* Get referral coupons for the current user.
*
* @return array An array of referral coupon codes for the current user.
*
* @since 1.0.0
*/
function ecre_referral_coupons() {
$referral_user_id = get_current_user_id();
// Try to get from cache first.
$cache_key = 'ecre_referral_coupon_' . $referral_user_id;
$cached_coupons = wp_cache_get( $cache_key, 'ecre_coupons' );
if ( false !== $cached_coupons ) {
return $cached_coupons;
}
global $wpdb;
// Direct database query - much faster than WP_Query with meta_query.
$result = $wpdb->get_row(
$wpdb->prepare(
"SELECT
p.ID as coupon_id,
p.post_title as coupon_code,
p.post_date as post_date,
pm_discount_type.meta_value as discount_type,
pm_amount.meta_value as discount
FROM {$wpdb->posts} p
INNER JOIN {$wpdb->postmeta} pm_referral
ON p.ID = pm_referral.post_id
AND pm_referral.meta_key = 'referral_user_id'
AND pm_referral.meta_value = %d
LEFT JOIN {$wpdb->postmeta} pm_discount_type
ON p.ID = pm_discount_type.post_id
AND pm_discount_type.meta_key = 'discount_type'
LEFT JOIN {$wpdb->postmeta} pm_amount
ON p.ID = pm_amount.post_id
AND pm_amount.meta_key = 'coupon_amount'
WHERE p.post_type = 'shop_coupon'
AND p.post_status = 'publish'
ORDER BY p.post_date ASC
LIMIT 1",
$referral_user_id
),
ARRAY_A
);
$coupons = array();
if ( $result ) {
$coupon_details = array(
'coupon_code' => $result['coupon_code'],
'discount_type' => $result['discount_type'],
'discount' => $result['discount'],
'generated_at' => gmdate( 'M d, Y', strtotime( $result['post_date'] ) ),
'coupon_id' => $result['coupon_id'],
);
$coupons[] = $coupon_details;
}
// Cache for 5 minutes.
wp_cache_set( $cache_key, $coupons, 'ecre_coupons', 30 );
return $coupons;
}
}
if ( ! function_exists( 'ecre_referral_coupons_with_usage' ) ) {
/**
* Retrieve an array of details for orders that used coupons with a referral_user_id,
* excluding orders of the current user.
*
* @return array An array of order details.
*/
function ecre_referral_coupons_with_usage() {
global $wpdb;
$user_id = get_current_user_id();
// Attempt to retrieve cached results.
$cached_results = wp_cache_get( 'ecre_pro_referral_coupon_invites_' . $user_id );
// If cached results are not available, execute the database query and cache the results.
if ( false === $cached_results ) {
$results = $wpdb->get_results(
$wpdb->prepare(
"
SELECT orders.id,
orders.status,
orders.date_created_gmt,
orders.billing_email,
postmeta_completed.meta_value AS referral_status
FROM {$wpdb->prefix}wc_orders AS orders
INNER JOIN {$wpdb->prefix}postmeta AS postmeta_referral
ON orders.id = postmeta_referral.post_id
LEFT JOIN {$wpdb->prefix}postmeta AS postmeta_completed
ON orders.id = postmeta_completed.post_id
AND postmeta_completed.meta_key = 'ecre_referral_order_completed'
WHERE postmeta_referral.meta_key = '_referral_user_id'
AND postmeta_referral.meta_value = %d
AND orders.status <> 'trash'
",
$user_id
),
ARRAY_A
);
// Cache the results.
wp_cache_set( 'ecre_pro_referral_coupon_invites_' . $user_id, $results, '', 3600 );
// Assign the results to the cached_results variable.
$cached_results = $results;
}
return $cached_results;
}
}
if ( ! function_exists( 'ecre_reward_coupons' ) ) {
/**
* Get reward coupons for the current user.
*
* @return array An array of reward coupon codes for the current user.
*
* @since 1.0.0
*/
function ecre_reward_coupons() {
global $wpdb;
$reward_user_id = get_current_user_id();
$query = "
SELECT
p.ID as coupon_id,
p.post_title as coupon_code,
p.post_date as generated_at,
COALESCE(pm1.meta_value, '') as discount_type,
COALESCE(pm2.meta_value, '') as discount,
COALESCE(pm3.meta_value, '') as usage_limit,
COALESCE(pm4.meta_value, '') as usage_count,
COALESCE(erc.expires_at, pm_expiry.meta_value, pm5.meta_value, '') as expiration_date
FROM
{$wpdb->prefix}posts p
LEFT JOIN
{$wpdb->prefix}postmeta pm1 ON p.ID = pm1.post_id AND pm1.meta_key = 'discount_type'
LEFT JOIN
{$wpdb->prefix}postmeta pm2 ON p.ID = pm2.post_id AND pm2.meta_key = 'coupon_amount'
LEFT JOIN
{$wpdb->prefix}postmeta pm3 ON p.ID = pm3.post_id AND pm3.meta_key = 'usage_limit'
LEFT JOIN
{$wpdb->prefix}postmeta pm4 ON p.ID = pm4.post_id AND pm4.meta_key = 'usage_count'
LEFT JOIN
{$wpdb->prefix}postmeta pm5 ON p.ID = pm5.post_id AND pm5.meta_key = 'date_expires'
LEFT JOIN
{$wpdb->prefix}postmeta pm_expiry ON p.ID = pm_expiry.post_id AND pm_expiry.meta_key = 'expiry_date'
LEFT JOIN
{$wpdb->prefix}ecre_reward_coupons erc ON p.ID = erc.coupon_id
WHERE
p.post_type = 'shop_coupon'
AND p.post_status = 'publish'
AND EXISTS (
SELECT 1
FROM {$wpdb->prefix}postmeta pm
WHERE pm.post_id = p.ID
AND pm.meta_key = 'reward_user_id'
AND pm.meta_value = %d
)
ORDER BY
p.post_date ASC
";
// phpcs:ignore
$results = $wpdb->get_results( $wpdb->prepare( $query, $reward_user_id ) );
// Process results to ensure date format is correct for frontend.
if ( ! empty( $results ) ) {
foreach ( $results as $key => $coupon ) {
if ( ! empty( $coupon->expiration_date ) ) {
// Check if it's a timestamp (numeric).
if ( is_numeric( $coupon->expiration_date ) ) {
$results[ $key ]->expiration_date = gmdate( 'Y-m-d', $coupon->expiration_date );
} elseif ( strpos( $coupon->expiration_date, '0000-00-00' ) !== false ) {
$results[ $key ]->expiration_date = '';
}
}
}
}
return $results;
}
}
if ( ! function_exists( 'ecre_has_orders' ) ) {
/**
* Check if a user has at least one order in WooCommerce.
*
* @return bool True if the user has at least one order, false otherwise.
*/
function ecre_has_orders() {
$user_id = get_current_user_id();
// Get completed orders for the user.
$args = array(
'customer' => $user_id,
);
$user_completed_orders = wc_get_orders( $args );
// Check if the user has at least one completed order.
return ! empty( $user_completed_orders ) ? true : false;
}
}
if ( ! function_exists( 'ecre_custom_currency_symbol' ) ) {
/**
* Get WooCommerce currency symbol
*
* @return string The currency symbol
*/
function ecre_custom_currency_symbol() {
// If WooCommerce is active, use its function to get currency symbol.
if ( function_exists( 'get_woocommerce_currency_symbol' ) ) {
$ecre_currency_sign = get_woocommerce_currency_symbol();
$ecre_currency_sign = str_replace( ' ', '', $ecre_currency_sign );
$ecre_currency_sign = html_entity_decode( $ecre_currency_sign );
return $ecre_currency_sign;
} else {
return '$';
}
}
}
if ( ! function_exists( 'ecre_get_currency_settings' ) ) {
/**
* Get all WooCommerce currency settings
*
* @return array Array containing all currency settings
*/
function ecre_get_currency_settings() {
$settings = array(
'symbol' => '$',
'position' => 'left',
'thousand_separator' => ',',
'decimal_separator' => '.',
'decimals' => 2,
);
// If WooCommerce is active, get actual settings.
if ( function_exists( 'get_woocommerce_currency_symbol' ) && function_exists( 'get_option' ) ) {
// Get currency symbol.
$currency_symbol = get_woocommerce_currency_symbol();
$currency_symbol = str_replace( ' ', '', $currency_symbol );
$currency_symbol = html_entity_decode( $currency_symbol );
$settings['symbol'] = $currency_symbol;
$settings['position'] = get_option( 'woocommerce_currency_pos', 'left' );
$settings['thousand_separator'] = get_option( 'woocommerce_price_thousand_sep', ',' );
$settings['decimal_separator'] = get_option( 'woocommerce_price_decimal_sep', '.' );
$settings['decimals'] = absint( get_option( 'woocommerce_price_num_decimals', 2 ) );
}
return $settings;
}
}
if ( ! function_exists( 'ecre_format_price' ) ) {
/**
* Format price with currency symbol and separators based on WooCommerce settings
*
* @param float|string $price The price to format.
* @param bool $include_symbol Whether to include currency symbol (default: true).
* @return string The formatted price with currency symbol
*/
function ecre_format_price( $price, $include_symbol = true ) {
// Get all currency settings.
$settings = ecre_get_currency_settings();
// Format the price with proper separators and decimals.
$formatted_price = number_format(
(float) $price,
$settings['decimals'],
$settings['decimal_separator'],
$settings['thousand_separator']
);
// Return without symbol if requested.
if ( ! $include_symbol ) {
return $formatted_price;
}
// Add currency symbol based on position.
switch ( $settings['position'] ) {
case 'left':
return $settings['symbol'] . $formatted_price;
case 'right':
return $formatted_price . $settings['symbol'];
case 'left_space':
return $settings['symbol'] . ' ' . $formatted_price;
case 'right_space':
return $formatted_price . ' ' . $settings['symbol'];
default:
return $settings['symbol'] . $formatted_price;
}
}
}
if ( ! function_exists( 'ecre_email_preview_data' ) ) {
/**
* Retrieves data for email preview.
*
* This function fetches various settings and data necessary for email preview,
* including referral and reward discounts, coupon codes, etc.
*
* @since 1.0.0
*
* @return array An array containing email preview data including:
* - 'referral_discount': The referral discount value with currency sign or percent.
* - 'reward_discount': The reward discount value with currency sign or percent.
* - 'referral_coupon_code': The referral coupon code.
* - 'reward_coupon_code': The reward coupon code.
*/
function ecre_email_preview_data() {
$ecre_currency_sign = ecre_custom_currency_symbol();
$referral_discount = '';
$reward_discount = '';
$referral_discount_type = '';
$reward_discount_type = '';
$coupon_code = '75V5KLDA';
$referral_coupon_code = '';
$current_user_id = get_current_user_id();
$referral_coupon = get_user_meta( $current_user_id, 'ecre_referral_coupon', true );
$referral_discount = get_option( 'ecre_referral_discount' );
$referral_discount_type = get_option( 'ecre_referral_discount_type' );
$referral_coupon_code = $referral_coupon ? $referral_coupon : 'ECHO75V5KLDA';
if ( 'percent' === $referral_discount_type ) {
$referral_discount = $referral_discount . '% ';
} else {
$referral_discount = $referral_discount . $ecre_currency_sign;
}
$reward_discount = get_option( 'ecre_reward_discount' );
$reward_discount_type = get_option( 'ecre_reward_discount_type' );
if ( 'percent' === $reward_discount_type ) {
$reward_discount = $reward_discount . '%';
} else {
$reward_discount = $reward_discount . $ecre_currency_sign;
}
$data = array(
'referral_discount' => $referral_discount,
'reward_discount' => $reward_discount,
'referral_coupon_code' => $referral_coupon_code,
'reward_coupon_code' => $coupon_code,
);
return $data;
}
}
if ( ! function_exists( 'ecre_check_pro_plugin_exists' ) ) {
/**
* Check if pro exists.
*/
function ecre_check_pro_plugin_exists() {
return file_exists( WP_PLUGIN_DIR . '/echo-rewards-pro/echo-rewards.php' );
}
}
if ( ! function_exists( 'ecre_get_all_product_categories' ) ) {
/**
* Retrieves all product categories.
*
* This function fetches all product categories, including empty ones.
*
* @return array List of product categories. Returns an empty array if an error occurs.
*/
function ecre_get_all_product_categories() {
$args = array(
'taxonomy' => 'product_cat',
'hide_empty' => false,
);
$product_categories = get_terms( $args );
if ( ! is_wp_error( $product_categories ) ) {
return $product_categories;
} else {
return array();
}
}
}
/**
* Update all referral coupons based on settings with cancellation support.
*/
function ecre_update_referral_coupons( $settings, $process_id = null ) {
global $wpdb;
$currency_symbol = ecre_pro_custom_currency_symbol();
$coupon_prefix = $settings['referralCouponPrefix'];
$coupon_prefix_upper = strtoupper( $coupon_prefix );
$coupon_prefix_lower = strtolower( $coupon_prefix );
$referral_discount = $settings['referralDiscount'];
$discount_type = $settings['referralCouponType']['value'];
$discount = ( 'percent' === $discount_type ) ? $referral_discount . '%' : $referral_discount . $currency_symbol;
$selected_product_ids = isset( $settings['referralIncludeProducts'] ) && is_array( $settings['referralIncludeProducts'] ) ? array_column( $settings['referralIncludeProducts'], 'value' ) : array();
$exclude_product_ids = isset( $settings['referralExcludeProducts'] ) && is_array( $settings['referralExcludeProducts'] ) ? array_column( $settings['referralExcludeProducts'], 'value' ) : array();
$selected_categories = isset( $settings['referralIncludeCategories'] ) && is_array( $settings['referralIncludeCategories'] ) ? array_column( $settings['referralIncludeCategories'], 'value' ) : array();
$exclude_categories = isset( $settings['referralExcludeCategories'] ) && is_array( $settings['referralExcludeCategories'] ) ? array_column( $settings['referralExcludeCategories'], 'value' ) : array();
$enable_subscription_limit = $settings['enableReferralLimitSubscriptionCoupon'];
$subscription_limit = $settings['referralLimitSubscriptionCoupon'];
$prefix_length = strlen( $coupon_prefix_lower );
// Update coupon posts with uppercase prefix in one query.
$wpdb->query(
$wpdb->prepare(
"
UPDATE {$wpdb->posts} AS p
INNER JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id
LEFT JOIN {$wpdb->postmeta} AS pm_custom ON p.ID = pm_custom.post_id AND pm_custom.meta_key = 'ecre_custom_referral'
SET
p.post_title = CASE
WHEN LOWER(SUBSTRING(p.post_title, 1, %d)) = %s THEN CONCAT(%s, SUBSTRING(p.post_title, %d))
ELSE CONCAT(%s, SUBSTRING(p.post_title, %d))
END,
p.post_name = CASE
WHEN LOWER(SUBSTRING(p.post_name, 1, %d)) = %s THEN CONCAT(%s, SUBSTRING(p.post_name, %d))
ELSE CONCAT(%s, SUBSTRING(p.post_name, %d))
END,
p.post_content = CASE
WHEN pm_custom.meta_value = '1' THEN p.post_content
ELSE %s
END,
p.post_excerpt = CASE
WHEN pm_custom.meta_value = '1' THEN p.post_excerpt
ELSE %s
END
WHERE
p.post_type = %s
AND pm.meta_key = %s
",
$prefix_length,
$coupon_prefix_lower,
$coupon_prefix_upper,
$prefix_length + 1,
$coupon_prefix_upper,
$prefix_length + 1,
$prefix_length,
$coupon_prefix_lower,
$coupon_prefix_upper,
$prefix_length + 1,
$coupon_prefix_upper,
$prefix_length + 1,
$discount . ' off coupon',
$discount . ' off coupon',
'shop_coupon',
'referral_user_id'
)
);
// Now update post_excerpt for custom coupons with their existing amount.
ecre_update_custom_coupon_excerpts( $currency_symbol, $discount_type );
// Update meta values in optimized batches.
ecre_update_referral_meta_batch( $referral_discount, $discount_type, $selected_product_ids, $exclude_product_ids, $selected_categories, $exclude_categories, $subscription_limit, $process_id );
ecre_update_referrers_coupon_codes_batch( $process_id );
}
/**
* Update referral_coupon_code in wp_ecre_referrers table with chunk processing
*/
function ecre_update_referrers_coupon_codes_batch( $process_id = null ) {
global $wpdb;
$batch_size = 500;
$offset = 0;
$processed = 0;
do {
// Check if process should be cancelled.
if ( $process_id ) {
$current_process = get_option( 'ecre_current_coupon_process' );
if ( $current_process !== $process_id ) {
return $processed;
}
}
// Get chunk of referrer IDs that need updating.
$referrer_chunk = $wpdb->get_results(
$wpdb->prepare(
"
SELECT r.id, r.referral_coupon_id
FROM {$wpdb->prefix}ecre_referrers r
INNER JOIN {$wpdb->posts} p ON r.referral_coupon_id = p.ID
WHERE r.referral_coupon_id IS NOT NULL
AND p.post_type = %s
AND (r.referral_coupon_code != p.post_title OR r.referral_coupon_code IS NULL)
LIMIT %d OFFSET %d
",
'shop_coupon',
$batch_size,
$offset
)
);
if ( empty( $referrer_chunk ) ) {
break;
}
// Extract referrer IDs and process in chunks (same pattern as ecre_update_referral_meta_batch).
$referrer_ids = wp_list_pluck( $referrer_chunk, 'id' );
if ( ! empty( $referrer_ids ) ) {
$chunk_size = 100;
$chunks = array_chunk( $referrer_ids, $chunk_size );
foreach ( $chunks as $chunk ) {
$referrer_ids_sanitized = array_map( 'absint', $chunk );
$query_args = array_merge(
array( current_time( 'mysql' ) ),
$referrer_ids_sanitized,
array( 'shop_coupon' )
);
// Following the exact same pattern as ecre_update_referral_meta_batch.
$wpdb->query(
$wpdb->prepare(
"
UPDATE {$wpdb->prefix}ecre_referrers r
INNER JOIN {$wpdb->posts} p ON r.referral_coupon_id = p.ID
SET r.referral_coupon_code = p.post_title,
r.updated_at = %s
WHERE r.id IN (" . implode( ',', array_fill( 0, count( $referrer_ids_sanitized ), '%d' ) ) . ')
AND p.post_type = %s',
$query_args
)
);
}
}
$processed += count( $referrer_chunk );
$offset += $batch_size;
// Memory management.
wp_cache_flush();
if ( function_exists( 'gc_collect_cycles' ) ) {
gc_collect_cycles();
}
$chunk_count = count( $referrer_chunk );
} while ( $chunk_count === $batch_size );
return $processed;
}
/**
* Update post_excerpt for custom referral coupons using their existing coupon_amount
*/
function ecre_update_custom_coupon_excerpts( $currency_symbol, $discount_type ) {
global $wpdb;
// Get all custom referral coupons with their existing coupon amounts.
$custom_coupons = $wpdb->get_results(
"SELECT p.ID, pm_amount.meta_value as coupon_amount
FROM {$wpdb->posts} AS p
INNER JOIN {$wpdb->postmeta} AS pm_referral ON p.ID = pm_referral.post_id AND pm_referral.meta_key = 'referral_user_id'
INNER JOIN {$wpdb->postmeta} AS pm_custom ON p.ID = pm_custom.post_id AND pm_custom.meta_key = 'ecre_custom_referral' AND pm_custom.meta_value = '1'
INNER JOIN {$wpdb->postmeta} AS pm_amount ON p.ID = pm_amount.post_id AND pm_amount.meta_key = 'coupon_amount'
WHERE p.post_type = 'shop_coupon'"
);
if ( ! empty( $custom_coupons ) ) {
foreach ( $custom_coupons as $coupon ) {
$existing_amount = floatval( $coupon->coupon_amount );
$custom_discount_text = ( 'percent' === $discount_type ) ?
$existing_amount . '%' :
$existing_amount . $currency_symbol;
// Update post_excerpt and post_content with existing amount.
wp_update_post(
array(
'ID' => $coupon->ID,
'post_excerpt' => $custom_discount_text . ' off coupon',
'post_content' => $custom_discount_text . ' off coupon',
)
);
}
}
}
if ( ! function_exists( 'ecre_update_referral_meta_batch' ) ) {
/**
* Batch update referral coupon meta data.
*
* Updates referral-related coupon meta values in controlled batches to avoid
* memory exhaustion and long-running queries. Custom referral coupons are
* excluded from amount updates while still receiving other meta updates.
*
* Supports process cancellation via a process ID to safely stop execution
* mid-way if required.
*
* @param float|int $referral_discount Discount amount for referral coupons.
* @param string $discount_type Coupon discount type (e.g. percent, fixed_cart).
* @param array $selected_product_ids Product IDs allowed for coupon usage.
* @param array $exclude_product_ids Product IDs excluded from coupon usage.
* @param array $selected_categories Product categories allowed for coupon usage.
* @param array $exclude_categories Product categories excluded from coupon usage.
* @param int $subscription_limit Subscription payment limit for coupons.
* @param string|null $process_id Optional process identifier for cancellation control.
*
* @return void
*/
function ecre_update_referral_meta_batch( $referral_discount, $discount_type, $selected_product_ids, $exclude_product_ids, $selected_categories, $exclude_categories, $subscription_limit, $process_id = null ) {
global $wpdb;
$batch_size = 500;
$offset = 0;
$processed = 0;
$skipped = 0;
do {
// Check if process should be cancelled.
if ( $process_id ) {
$current_process = get_option( 'ecre_current_coupon_process' );
if ( $current_process !== $process_id ) {
return;
}
}
// Get batch of coupon IDs.
$coupon_batch = $wpdb->get_results(
$wpdb->prepare(
"
SELECT p.ID
FROM {$wpdb->posts} AS p
INNER JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id
WHERE p.post_type = %s
AND pm.meta_key = %s
LIMIT %d OFFSET %d
",
'shop_coupon',
'referral_user_id',
$batch_size,
$offset
)
);
if ( empty( $coupon_batch ) ) {
break;
}
$coupon_ids = wp_list_pluck( $coupon_batch, 'ID' );
$custom_coupon_ids = array();
if ( ! empty( $coupon_ids ) ) {
$chunk_size = 100;
$chunks = array_chunk( $coupon_ids, $chunk_size );
foreach ( $chunks as $chunk ) {
$coupon_ids_sanitized = array_map( 'absint', $chunk );
$placeholders = implode( ',', array_fill( 0, count( $coupon_ids_sanitized ), '%d' ) );
$query_args = array_merge( array( 'ecre_custom_referral', '1' ), $coupon_ids_sanitized );
$chunk_custom_ids = $wpdb->get_col(
$wpdb->prepare(
"SELECT post_id
FROM {$wpdb->postmeta}
WHERE meta_key = %s
AND meta_value = %s
AND post_id IN (" . implode( ',', array_fill( 0, count( $coupon_ids_sanitized ), '%d' ) ) . ')',
$query_args
)
);
if ( ! empty( $chunk_custom_ids ) ) {
$custom_coupon_ids = array_merge( $custom_coupon_ids, $chunk_custom_ids );
}
}
}
// Separate regular coupons from custom ones.
$regular_coupon_ids = array_diff( $coupon_ids, $custom_coupon_ids );
// Update coupon_amount and discount_type for regular coupons only.
if ( ! empty( $regular_coupon_ids ) ) {
ecre_bulk_update_meta( 'coupon_amount', $referral_discount, $regular_coupon_ids );
}
// Update other meta fields for all coupons.
if ( ! empty( $coupon_ids ) ) {
ecre_bulk_update_meta( 'discount_type', $discount_type, $coupon_ids );
ecre_bulk_update_meta( 'product_ids', ( ! empty( $selected_product_ids ) ? implode( ',', $selected_product_ids ) : '' ), $coupon_ids );
ecre_bulk_update_meta( 'exclude_product_ids', ( ! empty( $exclude_product_ids ) ? implode( ',', $exclude_product_ids ) : '' ), $coupon_ids );
ecre_bulk_update_meta( 'product_categories', maybe_serialize( $selected_categories ), $coupon_ids );
ecre_bulk_update_meta( 'exclude_product_categories', maybe_serialize( $exclude_categories ), $coupon_ids );
ecre_bulk_update_meta( '_wcs_number_payments', $subscription_limit, $coupon_ids );
}
$processed += count( $coupon_ids );
$skipped += count( $custom_coupon_ids );
$offset += $batch_size;
$coupon_batch_count = count( $coupon_batch );
// Enhanced memory management.
wp_cache_flush();
if ( function_exists( 'gc_collect_cycles' ) ) {
gc_collect_cycles();
}
} while ( $coupon_batch_count === $batch_size );
}
}
if ( ! function_exists( 'ecre_bulk_update_meta' ) ) {
/**
* Bulk insert or update post meta for multiple posts.
*
* Efficiently updates or inserts a specific meta key/value pair for a list
* of post IDs using chunked processing to reduce memory usage.
*
* @param string $meta_key Meta key to update.
* @param mixed $meta_value Meta value to store (will be serialized if needed).
* @param array $post_ids Array of post IDs to update.
*
* @return void
*/
function ecre_bulk_update_meta( $meta_key, $meta_value, $post_ids ) {
global $wpdb;
if ( empty( $post_ids ) ) {
return;
}
$meta_value = maybe_serialize( $meta_value );
$post_ids = array_map( 'absint', $post_ids );
$chunk_size = 25;
$chunks = array_chunk( $post_ids, $chunk_size );
foreach ( $chunks as $chunk ) {
foreach ( $chunk as $post_id ) {
$existing_meta = $wpdb->get_var(
$wpdb->prepare(
"SELECT meta_id FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = %s",
$post_id,
$meta_key
)
);
if ( $existing_meta ) {
$wpdb->update(
$wpdb->postmeta,
array( 'meta_value' => $meta_value ),
array( 'meta_id' => $existing_meta ),
array( '%s' ),
array( '%d' )
);
} else {
$wpdb->insert(
$wpdb->postmeta,
array(
'post_id' => $post_id,
'meta_key' => $meta_key,
'meta_value' => $meta_value,
),
array( '%d', '%s', '%s' )
);
}
}
// Memory cleanup after each chunk.
if ( function_exists( 'gc_collect_cycles' ) ) {
gc_collect_cycles();
}
}
}
}
if ( ! function_exists( 'ecre_get_all_wp_pages' ) ) {
/**
* Retrieves all WordPress pages.
*
* This function queries the WordPress database to fetch and return
* an array of all published pages, including their IDs, titles, and
* other relevant data. It can be used to display a list of pages
* or for further processing in the application.
*
* @since 1.0.0
* @return array An array of all WordPress pages with their details.
*/
function ecre_get_all_wp_pages() {
// Get the home page data.
$home_page = array(
'value' => 0,
'label' => 'Home',
'slug' => 'home',
'url' => home_url( '/' ),
);
// Get all other pages.
$pages = get_pages();
// Initialize the page list with the home page.
$page_list = array( $home_page );
// Loop through each page and get the relevant data.
foreach ( $pages as $page ) {
$page_list[] = array(
'value' => $page->ID,
'label' => $page->post_title,
'slug' => $page->post_name,
'url' => get_permalink( $page->ID ),
);
}
return $page_list;
}
}
if ( ! function_exists( 'ecre_pro_first_coupon_order_date' ) ) {
/**
* Retrieves the date of the first coupon order for a specific user.
*
* @param int $user_id The ID of the user.
*
* @return string|null The date of the first coupon order, or null if no such order is found.
*/
function ecre_pro_first_coupon_order_date( $user_id ) {
// Retrieve all orders for the user.
$usages_coupon = ecre_pro_referral_coupons_with_usage();
// Loop through the user's orders to find the actual first coupon order date.
foreach ( $usages_coupon as $user_order ) {
$order_obj = wc_get_order( $user_order['id'] );
$referral_user_id = $order_obj->get_user_id();
// Check if coupons were used.
if ( $user_id && ! empty( $referral_user_id ) ) {
// Return the date of the first coupon order found.
return $order_obj->get_date_created()->format( 'Y-m-d' );
}
}
return null;
}
}
if ( ! function_exists( 'ecre_pro_custom_currency_symbol' ) ) {
/**
* Get WooCommerce currency symbol
*
* @return string The currency symbol
*/
function ecre_pro_custom_currency_symbol() {
// If WooCommerce is active, use its function to get currency symbol.
if ( function_exists( 'get_woocommerce_currency_symbol' ) ) {
$ecre_currency_sign = get_woocommerce_currency_symbol();
$ecre_currency_sign = html_entity_decode( $ecre_currency_sign );
return $ecre_currency_sign;
} else {
return '$';
}
}
}
if ( ! function_exists( 'ecre_monthly_referral_coupons_usage' ) ) {
/**
* Counts the number of orders in the current month that are associated with coupons having the referral user ID meta set to the current user.
*
* This function retrieves all coupons associated with the current user's referral ID and counts the number of orders placed in the current month that have used these coupons.
*
* @return int The count of orders in the current month using referral coupons associated with the current user.
*/
function ecre_monthly_referral_coupons_usage() {
$current_user_id = get_current_user_id();
$coupon_usage_count = 0;
$current_month = gmdate( 'm' );
$current_year = gmdate( 'Y' );
$args = array(
'post_type' => 'shop_coupon',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'referral_user_id',
'value' => $current_user_id,
'compare' => '=',
),
),
'orderby' => 'date',
'order' => 'ASC',
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
$coupon_code = strtolower( get_the_title() );
// Get orders based on the coupon code.
$orders = wc_get_orders(
array(
'date_query' => array(
array(
'year' => $current_year,
'month' => $current_month,
),
),
'numberposts' => -1,
'post_type' => 'shop_order',
)
);
foreach ( $orders as $order ) {
$coupon_codes = array_map( 'strtolower', $order->get_coupon_codes() );
if ( ! empty( $coupon_codes ) ) {
// Check if the coupon code is in the array of used coupons.
if ( in_array( $coupon_code, $coupon_codes, true ) ) {
// Check if the order has the _referral_user_id meta.
if ( (int) get_post_meta( $order->get_id(), '_referral_user_id', true ) === (int) $current_user_id ) {
++$coupon_usage_count;
}
}
}
}
update_post_meta( get_the_ID(), 'referral_usage_count', $coupon_usage_count );
}
wp_reset_postdata();
}
return $coupon_usage_count;
}
}
if ( ! function_exists( 'ecre_pro_get_all_orders' ) ) {
/**
* Retrieves all orders from the WooCommerce store.
*
* This function queries the WooCommerce database to fetch and return
* an array of all orders, including their details such as order IDs,
* statuses, and customer information. It can be used for order management,
* reporting, or analysis purposes within the application.
*
* @since 1.0.0
* @return array An array of all WooCommerce orders with their details.
*/
function ecre_pro_get_all_orders() {
global $wpdb;
// Attempt to retrieve cached results.
$cached_results = wp_cache_get( 'ecre_pro_all_orders' );
// If cached results are not available, execute the database query and cache the results.
if ( false === $cached_results ) {
$results = $wpdb->get_results(
"
SELECT
orders.id,
orders.status,
orders.date_created_gmt,
orders.billing_email
FROM {$wpdb->prefix}wc_orders AS orders
WHERE orders.status <> 'trash'
",
ARRAY_A
);
// Cache the results.
wp_cache_set( 'ecre_pro_all_orders', $results, '', 3600 );
// Assign the results to the cached_results variable.
$cached_results = $results;
}
return $cached_results;
}
}
if ( ! function_exists( 'ecre_get_expiry_status' ) ) {
/**
* Check if the given expiry date is expired or still available.
*
* @param string $expiry_date The expiry date to check (format: 'Y-m-d').
* @return string The status of the reward: 'Expired', 'Available', or 'Not Set'.
*/
function ecre_get_expiry_status( $expiry_date ) {
// Check if the expiry date is not empty or invalid.
if ( $expiry_date ) {
// Get the current date in the same format as the expiry date.
$current_date = gmdate( 'Y-m-d' );
$erce_settings = get_option( 'ecre_settings', array() );
// Compare the expiry date with the current date.
if ( strtotime( $expiry_date ) < strtotime( $current_date ) ) {
if ( 'delete' === $erce_settings['rewardPointExpiryAction']['value'] ) {
return 'expired';
}
if ( 'unavailable' === $erce_settings['rewardPointExpiryAction']['value'] ) {
return 'unavailable';
}
} else {
return 'available';
}
}
return 'Not Set';
}
}
if ( ! function_exists( 'ecre_get_discount_data' ) ) {
/**
* Retrieves discount data for the specified period.
*
* @param string $period The period for which to retrieve data. Possible values: 'last_month', 'current_month', '7_days', 'yearly'.
*
* @return array Discount data including total discounts and referral discounts by date.
*/
function ecre_get_discount_data( $period ) {
global $wpdb;
$date_series_query = '';
if ( 'last_month' === $period ) {
$date_series_query = "
SELECT DATE_FORMAT(CURDATE() - INTERVAL n DAY, '%Y-%m-%d') AS order_date
FROM (
SELECT a.N + b.N * 10 AS n
FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a,
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
) num
WHERE DATE_FORMAT(CURDATE() - INTERVAL n DAY, '%Y-%m') = DATE_FORMAT(CURDATE() - INTERVAL 1 MONTH, '%Y-%m')
";
} elseif ( 'current_month' === $period ) {
$date_series_query = "
SELECT DATE_FORMAT(CURDATE() - INTERVAL n DAY, '%Y-%m-%d') AS order_date
FROM (
SELECT a.N + b.N * 10 AS n
FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a,
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
) num
WHERE DATE_FORMAT(CURDATE() - INTERVAL n DAY, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
";
} elseif ( '7_days' === $period ) {
$date_series_query = '
SELECT CURDATE() - INTERVAL n DAY AS order_date
FROM (
SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
) days
';
} elseif ( 'yearly' === $period ) {
$date_series_query = "
SELECT DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL -n MONTH), '%Y-%m') AS order_date
FROM (
SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11
) months
WHERE DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL -n MONTH), '%Y') = DATE_FORMAT(CURDATE(), '%Y')
";
} else {
return array(); // Invalid period, return empty result.
}
$cache_key = 'discount_data_' . md5( $period );
$cached_data = wp_cache_get( $cache_key, 'custom_cache_group' );
if ( false !== $cached_data ) {
return $cached_data;
}
$query = "
WITH date_series AS (
{$date_series_query}
)
SELECT
ds.order_date,
COALESCE(SUM(oim.meta_value), 0) AS total_discount,
COALESCE(SUM(CASE WHEN pm.meta_key = '_referral_user_id' THEN oim.meta_value ELSE 0 END), 0) AS total_discount_with_referral
FROM
date_series AS ds
LEFT JOIN
{$wpdb->prefix}wc_orders AS o
ON (
('yearly' = '{$period}' AND DATE_FORMAT(o.date_created_gmt, '%Y-%m') = ds.order_date)
OR ('yearly' != '{$period}' AND DATE(o.date_created_gmt) = ds.order_date)
)
LEFT JOIN
{$wpdb->prefix}woocommerce_order_items AS oi
ON o.id = oi.order_id
LEFT JOIN
{$wpdb->prefix}woocommerce_order_itemmeta AS oim
ON oi.order_item_id = oim.order_item_id
AND oim.meta_key = 'discount_amount'
AND oi.order_item_type = 'coupon'
LEFT JOIN
{$wpdb->prefix}postmeta AS pm
ON o.id = pm.post_id
AND pm.meta_key = '_referral_user_id'
GROUP BY
ds.order_date
ORDER BY
ds.order_date ASC
";
//phpcs:ignore
$results = $wpdb->get_results( $query, ARRAY_A );
// Cache the results.
wp_cache_set( $cache_key, $results, 'custom_cache_group', HOUR_IN_SECONDS );
return $results;
}
}
if ( ! function_exists( 'ecre_get_sales_data' ) ) {
/**
* Retrieves total sales data for the specified period.
*
* @param string $period The period for which to retrieve data. Possible values: 'last_month', 'current_month', '7_days', 'yearly'.
*
* @return array Sales data including total sales and referral sales by date.
*/
function ecre_get_sales_data( $period ) {
global $wpdb;
$date_series_query = '';
if ( 'last_month' === $period ) {
$date_series_query = "
SELECT DATE_FORMAT(CURDATE() - INTERVAL n DAY, '%Y-%m-%d') AS order_date
FROM (
SELECT a.N + b.N * 10 AS n
FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a,
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
) num
WHERE DATE_FORMAT(CURDATE() - INTERVAL n DAY, '%Y-%m') = DATE_FORMAT(CURDATE() - INTERVAL 1 MONTH, '%Y-%m')
";
} elseif ( 'current_month' === $period ) {
$date_series_query = "
SELECT DATE_FORMAT(CURDATE() - INTERVAL n DAY, '%Y-%m-%d') AS order_date
FROM (
SELECT a.N + b.N * 10 AS n
FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a,
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
) num
WHERE DATE_FORMAT(CURDATE() - INTERVAL n DAY, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
";
} elseif ( '7_days' === $period ) {
$date_series_query = '
SELECT CURDATE() - INTERVAL n DAY AS order_date
FROM (
SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
) days
';
} elseif ( 'yearly' === $period ) {
$date_series_query = "
SELECT DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL -n MONTH), '%Y-%m') AS order_date
FROM (
SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11
) months
WHERE DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL -n MONTH), '%Y') = DATE_FORMAT(CURDATE(), '%Y')
";
} else {
return array(); // Invalid period, return empty result.
}
$cache_key = 'sales_data_' . md5( $period );
$cached_data = wp_cache_get( $cache_key, 'custom_cache_group' );
if ( false !== $cached_data ) {
return $cached_data;
}
$query = "
WITH date_series AS (
{$date_series_query}
)
SELECT
ds.order_date,
COALESCE(SUM(oim.meta_value), 0) AS total_sales,
COALESCE(SUM(CASE WHEN pm.meta_key = '_referral_user_id' THEN oim.meta_value ELSE 0 END), 0) AS total_sales_with_referral
FROM
date_series AS ds
LEFT JOIN
{$wpdb->prefix}wc_orders AS o
ON (
('yearly' = '{$period}' AND DATE_FORMAT(o.date_created_gmt, '%Y-%m') = ds.order_date)
OR ('yearly' != '{$period}' AND DATE(o.date_created_gmt) = ds.order_date)
)
LEFT JOIN
{$wpdb->prefix}woocommerce_order_items AS oi
ON o.id = oi.order_id
LEFT JOIN
{$wpdb->prefix}woocommerce_order_itemmeta AS oim
ON oi.order_item_id = oim.order_item_id
AND oim.meta_key = '_line_total'
AND oi.order_item_type = 'line_item'
LEFT JOIN
{$wpdb->prefix}postmeta AS pm
ON o.id = pm.post_id
AND pm.meta_key = '_referral_user_id'
GROUP BY
ds.order_date
ORDER BY
ds.order_date ASC
";
//phpcs:ignore
$results = $wpdb->get_results( $query, ARRAY_A );
// Cache the results.
wp_cache_set( $cache_key, $results, 'custom_cache_group', HOUR_IN_SECONDS );
return $results;
}
}
if ( ! function_exists( 'ecre_get_referral_order_data' ) ) {
/**
* Fetches referral order data for a specific period.
*
* Generates date series for the given period ('last_month', 'current_month',
* '7_days', or 'yearly') and retrieves the count of referral orders. Results are cached.
*
* @param string $period Time period for the data (e.g., 'last_month').
* @return array Array of `order_date` and `referral_order_count`. Empty if invalid period.
*/
function ecre_get_referral_order_data( $period ) {
global $wpdb;
// Generate the date series query based on the provided period.
$date_series_query = '';
if ( 'last_month' === $period ) {
$date_series_query = "
SELECT DATE_FORMAT(CURDATE() - INTERVAL n DAY, '%Y-%m-%d') AS order_date
FROM (
SELECT a.N + b.N * 10 AS n
FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a,
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
) num
WHERE DATE_FORMAT(CURDATE() - INTERVAL n DAY, '%Y-%m') = DATE_FORMAT(CURDATE() - INTERVAL 1 MONTH, '%Y-%m')
";
} elseif ( 'current_month' === $period ) {
$date_series_query = "
SELECT DATE_FORMAT(CURDATE() - INTERVAL n DAY, '%Y-%m-%d') AS order_date
FROM (
SELECT a.N + b.N * 10 AS n
FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a,
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
) num
WHERE DATE_FORMAT(CURDATE() - INTERVAL n DAY, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
";
} elseif ( '7_days' === $period ) {
$date_series_query = '
SELECT CURDATE() - INTERVAL n DAY AS order_date
FROM (
SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
) days
';
} elseif ( 'yearly' === $period ) {
$date_series_query = "
SELECT DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL -n MONTH), '%Y-%m') AS order_date
FROM (
SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11
) months
WHERE DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL -n MONTH), '%Y') = DATE_FORMAT(CURDATE(), '%Y')
";
} else {
return array(); // Invalid period, return empty result.
}
$cache_key = 'referral_order_data_' . md5( $period );
$cached_data = wp_cache_get( $cache_key, 'custom_cache_group' );
if ( false !== $cached_data ) {
return $cached_data;
}
$query = "
WITH date_series AS (
{$date_series_query}
)
SELECT
ds.order_date,
COALESCE(COUNT(DISTINCT CASE WHEN pm.meta_key = '_referral_user_id' THEN o.id ELSE NULL END), 0) AS referral_order_count
FROM
date_series AS ds
LEFT JOIN
{$wpdb->prefix}wc_orders AS o
ON (
('yearly' = '{$period}' AND DATE_FORMAT(o.date_created_gmt, '%Y-%m') = ds.order_date)
OR ('yearly' != '{$period}' AND DATE(o.date_created_gmt) = ds.order_date)
)
LEFT JOIN
{$wpdb->prefix}postmeta AS pm
ON o.id = pm.post_id
AND pm.meta_key = '_referral_user_id'
GROUP BY
ds.order_date
ORDER BY
ds.order_date ASC
";
// Run the query and fetch results.
//phpcs:ignore
$results = $wpdb->get_results( $query, ARRAY_A );
// Cache the results.
wp_cache_set( $cache_key, $results, 'custom_cache_group', HOUR_IN_SECONDS );
return $results;
}
}
if ( ! function_exists( 'ecre_get_top_10_coupons_with_referral' ) ) {
/**
* Get top 10 coupons with discount details within a given time period.
*
* @param string $time_period Allowed values: 'last_month', 'current_month', '7_days', 'yearly'.
* @return array Top 10 coupons data.
*/
function ecre_get_top_10_coupons_with_referral( $time_period = 'current_month' ) {
global $wpdb;
// Table names with prefixes.
$orders_table = $wpdb->prefix . 'wc_orders';
$order_items_table = $wpdb->prefix . 'woocommerce_order_items';
$order_itemmeta_table = $wpdb->prefix . 'woocommerce_order_itemmeta';
$postmeta_table = $wpdb->prefix . 'postmeta';
// Define date conditions based on the time period.
$date_condition = '';
switch ( $time_period ) {
case 'last_month':
$date_condition = "o.date_created_gmt BETWEEN DATE_FORMAT(NOW() - INTERVAL 1 MONTH, '%Y-%m-01') AND LAST_DAY(NOW() - INTERVAL 1 MONTH)";
break;
case 'current_month':
$date_condition = "o.date_created_gmt BETWEEN DATE_FORMAT(NOW(), '%Y-%m-01') AND LAST_DAY(NOW())";
break;
case '7_days':
$date_condition = 'o.date_created_gmt >= DATE_SUB(NOW(), INTERVAL 7 DAY)';
break;
case 'yearly':
$date_condition = "o.date_created_gmt BETWEEN DATE_FORMAT(NOW(), '%Y-01-01') AND DATE_FORMAT(NOW(), '%Y-12-31')";
break;
default:
$date_condition = 'o.date_created_gmt >= DATE_SUB(NOW(), INTERVAL 7 DAY)';
break;
}
// Set up cache key for transient caching.
$cache_key = "top_10_coupons_{ $time_period }";
$cached_data = wp_cache_get( $cache_key );
// If cached data exists, return it.
if ( false !== $cached_data ) {
return $cached_data;
}
// SQL query to fetch top 10 coupons.
$query = "
SELECT
oi.order_item_name AS coupon_code,
COUNT(o.id) AS total_orders,
SUM(oim.meta_value) AS total_discount,
DATE_FORMAT(o.date_created_gmt, '%Y-%m-%d') AS creation_date,
'N/A' AS expiration_date, -- Placeholder for expiration
'percent' AS discount_type -- Placeholder for discount type
FROM
{$order_items_table} AS oi
INNER JOIN
{$orders_table} AS o ON oi.order_id = o.id
INNER JOIN
{$order_itemmeta_table} AS oim
ON oi.order_item_id = oim.order_item_id
AND oim.meta_key = 'discount_amount'
LEFT JOIN
{$postmeta_table} AS pm
ON pm.post_id = oi.order_id
AND pm.meta_key = '_referral_user_id'
WHERE
oi.order_item_type = 'coupon'
AND pm.meta_value IS NOT NULL
AND {$date_condition}
GROUP BY
oi.order_item_name, DATE_FORMAT(o.date_created_gmt, '%Y-%m-%d')
ORDER BY
total_discount DESC
LIMIT 10
";
// Execute the query.
//phpcs:ignore
$results = $wpdb->get_results( $query );
// Cache the results for 1 hour.
wp_cache_set( $cache_key, $results, '', HOUR_IN_SECONDS );
return $results;
}
}
if ( ! function_exists( 'ecre_is_woocommerce_subscriptions_active' ) ) {
/**
* Checks if the WooCommerce Subscriptions plugin is active.
*
* This function determines whether the WooCommerce Subscriptions plugin is
* currently active, either at the site level or network-wide in a multisite setup.
*
* @return bool True if WooCommerce Subscriptions is active, false otherwise.
*/
function ecre_is_woocommerce_subscriptions_active() {
// Get the list of active plugins from the database.
$active_plugins = get_option( 'active_plugins', array() );
// Check if WooCommerce Subscriptions is in the list of active plugins.
if ( in_array( 'woocommerce-subscriptions/woocommerce-subscriptions.php', $active_plugins, true ) ) {
return true;
}
// For multisite installations, check the network-activated plugins.
if ( is_multisite() ) {
$active_network_plugins = get_site_option( 'active_sitewide_plugins', array() );
if ( isset( $active_network_plugins['woocommerce-subscriptions/woocommerce-subscriptions.php'] ) ) {
return true;
}
}
return false;
}
}
if ( ! function_exists( 'ecre_get_woocommerce_order_statuses' ) ) {
/**
* Retrieves the available WooCommerce order statuses and formats them for use in select options.
*
* This function checks if the `wc_get_order_statuses` function exists, then fetches the WooCommerce
* order statuses and formats them into an array of arrays containing 'value' (order status key)
* and 'label' (order status name) to be used in form select options.
*
* @return array An array of order status options, each containing a 'value' and 'label'.
* Returns an empty array if WooCommerce is not available or order statuses cannot be fetched.
*
* @since 1.0.0
*/
function ecre_get_woocommerce_order_statuses() {
if ( ! function_exists( 'wc_get_order_statuses' ) ) {
return array();
}
$statuses = wc_get_order_statuses();
$status_options = array_map(
function ( $label, $key ) {
return array(
'value' => $key,
'label' => $label,
);
},
array_values( $statuses ),
array_keys( $statuses )
);
return $status_options;
}
}
}
if ( ! function_exists( 'ecre_is_pro_latest_version' ) ) {
/**
* Checks if a specified plugin is active and running a version that is at least 2.0.
*
* This function determines whether the specified plugin is active and if its version
* is greater than or equal to 2.0. It uses the WordPress filesystem API to safely
* access and read the plugin file.
*
* @param string $plugin_path Relative path to the plugin's main file within the `wp-content/plugins/` directory.
* Example: 'plugin-folder/plugin-main-file.php'.
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem object for handling file operations.
*
* @return bool True if the plugin is active and its version is 2.0 or higher. False otherwise.
*/
function ecre_is_pro_latest_version( $plugin_path ) {
global $wp_filesystem;
if ( is_plugin_active( $plugin_path ) ) {
// Initialize WordPress filesystem API.
if ( ! function_exists( 'WP_Filesystem' ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
}
WP_Filesystem();
// Get the plugin's main file path.
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_path;
// Read the file safely.
if ( $wp_filesystem->exists( $plugin_file ) ) {
$plugin_contents = $wp_filesystem->get_contents( $plugin_file );
// Extract the version using regex.
preg_match( '/^ \* Version:\s*(.*)$/mi', $plugin_contents, $matches );
$plugin_version = isset( $matches[1] ) ? trim( $matches[1] ) : '';
// Compare the version.
return version_compare( $plugin_version, '2.0', '>=' );
}
}
return false;
}
}
if ( ! function_exists( 'ecre_default_settings' ) ) {
/**
* Retrieves the default settings for the ECRE plugin.
*
* This function defines and returns the default configuration settings
* used by the ECRE plugin. It ensures that all necessary settings are
* available and set to their initial values when the plugin is activated
* or when settings are reset.
*
* @since 1.0.0
* @return array An associative array containing the default settings.
*/
function ecre_default_settings() {
$referral_discount_type = get_option( 'ecre_referral_discount_type', 'percent' );
$referral_discount_type_label = 'Percentage';
$reward_discount_type = get_option( 'ecre_reward_discount_type', 'percent' );
$reward_discount_type_label = 'Percentage';
$referral_widget_possition = get_option( 'vertical_left', 'left' );
$referral_widget_possition_label = 'Vertical left';
if ( ! empty( $referral_widget_possition ) ) {
if ( 'vertical_left' === $referral_widget_possition ) {
$referral_widget_possition = 'left';
$referral_widget_possition_label = 'Vertical left';
} elseif ( 'vertical_right' === $referral_widget_possition ) {
$referral_widget_possition = 'right';
$referral_widget_possition_label = 'Vertical right';
}
}
if ( ! empty( $referral_discount_type ) ) {
if ( 'percent' === $referral_discount_type ) {
$referral_discount_type_label = 'Percentage';
} elseif ( 'fixed' === $referral_discount_type ) {
$referral_discount_type_label = 'Fixed';
}
}
if ( ! empty( $reward_discount_type ) ) {
if ( 'percent' === $reward_discount_type ) {
$reward_discount_type_label = 'Percentage';
} elseif ( 'fixed' === $reward_discount_type ) {
$reward_discount_type_label = 'Fixed';
}
}
return array(
'enableReferralProgram' => get_option( 'ecre_referral_program_status', 1 ),
'enableReferralLink' => '',
'referralDiscount' => get_option( 'ecre_referral_discount', 5 ),
'noOrderMessageToReferrer' => get_option( 'ecre_referral_status_message', 'You need to have at-least an order in your account before you can refer others' ),
'referralWidgetPosition' => array(
'value' => $referral_widget_possition,
'label' => $referral_widget_possition_label,
),
'referralDiscountCapping' => get_option( 'ecre_referral_discount_capping', 0 ),
'referralMenuName' => get_option( 'ecre_referral_menu_name', 'EchoRewards Program' ),
'referralMonthlyLimit' => get_option( 'ecre_monthly_referral_limit', 5 ),
'referralMinimumPurchaseAmount' => get_option( 'ecre_referral_minimum_purchase_amount', 0 ),
'referralCouponPrefix' => get_option( 'ecre_referral_coupon_prefix', 'ECHO' ),
'canRefferOthers' => get_option( 'ecre_referral_status', '' ),
'canUseReferralCoupon' => get_option( 'ecre_referral_new_customer', '' ),
'enableReferralLimit' => '',
'enableTabOnWooCommerceProduct' => get_option( 'ecre_referral_tab_on_product_page', 1 ),
'enableReferralFloatingWidget' => get_option( 'ecre_referral_floating_widget', false ),
'enableReferralSocialSharing' => get_option( 'ecre_referral_social_sharing', 1 ),
'hideReferralMenuIcon' => get_option( 'ecre_hide_referral_menu_icon', '' ),
'is_user_loggedin' => '',
'pagesForWidgets' => array(
array(
'value' => 0,
'label' => 'Home',
'slug' => 'home',
'url' => '',
),
array(
'value' => 27,
'label' => 'Cart',
'slug' => 'cart',
'url' => '',
),
array(
'value' => 9,
'label' => 'My account',
'slug' => 'my-account',
'url' => '',
),
array(
'value' => 6,
'label' => 'Shop',
'slug' => 'shop',
'url' => '',
),
array(
'value' => 8,
'label' => 'Checkout',
'slug' => 'checkout',
'url' => '',
),
),
'referralIncludeProducts' => array(),
'referralExcludeProducts' => array(),
'referralIncludeCategories' => array(),
'referralExcludeCategories' => array(),
'referralCouponType' => array(
'value' => $referral_discount_type,
'label' => $referral_discount_type_label,
),
'socialMediaOptions' => array(
array(
'label' => 'Facebook',
'value' => 'Facebook',
),
array(
'label' => 'WhatsApp',
'value' => 'WhatsApp',
),
),
'rewardType' => array(
'value' => $reward_discount_type,
'label' => $reward_discount_type_label,
),
'rewardPointExpiryAction' => array(
'value' => 'unavailable',
'label' => 'Make the available points unavailable',
),
'rewardPoint' => 10,
'redeemPoint' => 1,
'redeemLimit' => 5,
'enableRedeemLimit' => 1,
'enableRewardPointExpiry' => '',
'rewardPointExpiry' => 7,
'minimumRewardPointAmount' => 25,
'redeemDiscount' => 1,
'rewardDiscount' => get_option( 'ecre_reward_discount', 5 ),
'rewardDiscountCapping' => get_option( 'ecre_reward_discount_capping', 0 ),
'rewardMinimumPurchaseAmount' => get_option( 'ecre_reward_minimum_purchase_amount', 0 ),
'enableRewardExpiry' => '',
'rewardCouponValidity' => get_option( 'ecre_reward_coupon_validity', 7 ),
'enableRewardCouponUsageLimit' => '',
'rewardCouponUsageLimit' => get_option( 'ecre_reward_coupon_usage_limit', 1 ),
'rewardIncludeProducts' => array(),
'rewardExcludeProducts' => array(),
'rewardIncludeCategories' => array(),
'rewardExcludeCategories' => array(),
'enableRefferalEmailInvitation' => get_option( 'ecre_referral_enable_email_notifications', 1 ),
'referralEmailSubject' => get_option( 'ecre_referral_email_subject', 'Here is a discount for you!' ),
'referralEmailHeading' => get_option( 'ecre_referral_email_heading', 'Discount for your first purchase on ' . site_url() ),
'referralEmailBody' => get_option( 'ecre_referral_email_description', site_url() . ' has some awesome products. Check them out with an awesome discount for your first purchase. Use the coupon code during checkout or visit the link and purchase' ),
'enableRewardEmailInvitation' => get_option( 'ecre_reward_enable_email_notifications', 1 ),
'rewardEmailSubject' => get_option( 'ecre_reward_email_subject', 'You got rewards!' ),
'rewardEmailHeading' => get_option( 'ecre_reward_email_heading', 'Congratulations! You have received a new reward' ),
'rewardEmailBody' => get_option( 'ecre_reward_email_description', 'You\'ve received a new reward by sharing your coupon code & referral link' ),
'referralMenuIcon' => get_option( 'ecre_referral_icon', '' ),
'referralSignupCouponNote' => 'This coupon can be applied for subscription sign up fee discount only',
'referralRecurringCouponNote' => 'This coupon can be applied for subscription renewal fee discount only',
'enableReferralLimitSubscriptionCoupon' => '',
'referralLimitSubscriptionCoupon' => 5,
'enableRewardLimitSubscriptionCoupon' => '',
'rewardLimitSubscriptionCoupon' => 5,
'enableRewardDelayTime' => false,
'rewardDelayTime' => 0,
'rewardOrderStatus' => array(
'value' => 'wc-completed',
'label' => 'Completed',
),
);
}
if ( ! function_exists( 'ecre_calculate_coupon_discount_amount' ) ) {
function ecre_calculate_coupon_discount_amount( $order, $coupon_code ) {
$discount_amount = 0;
foreach ( $order->get_items( 'coupon' ) as $item ) {
if ( $item->get_code() === $coupon_code ) {
$discount_amount = abs( $item->get_discount() );
break;
}
}
return $discount_amount;
}
}
if ( ! function_exists( 'ecre_get_customer_names_from_order' ) ) {
/**
* Retrieves the customer's name information from the order.
*
* This function extracts the billing first name, last name, and full name from the provided WooCommerce order object.
* If the full name is empty, it attempts to retrieve the user's display name from the WordPress user data. If no user
* is associated with the order, it defaults to 'Guest'.
*
* @since 1.0.0
*
* @param \WC_Order $order The WooCommerce order object from which customer details are extracted.
*
* @return array An associative array containing the customer's first name, last name, and full name:
* - `firstname`: The customer's billing first name.
* - `lastname`: The customer's billing last name.
* - `fullname`: The customer's full name, or 'Guest' if not available.
*/
function ecre_get_customer_names_from_order( $order ) {
$firstname = $order->get_billing_first_name();
$lastname = $order->get_billing_last_name();
$fullname = trim( $firstname . ' ' . $lastname );
if ( empty( $fullname ) ) {
$user_id = $order->get_user_id();
if ( $user_id ) {
$user = get_user_by( 'id', $user_id );
$fullname = $user ? $user->display_name : 'Guest';
} else {
$fullname = 'Guest';
}
}
return array(
'firstname' => $firstname,
'lastname' => $lastname,
'fullname' => $fullname,
);
}
}
if ( ! function_exists( 'ecre_merge_with_custom_settings' ) ) {
/**
* Merges global settings with user-specific custom settings.
*
* This function merges the provided global settings with custom settings for a specific user. If no user ID is provided
* or if no custom settings exist for the user, the function returns the global settings as-is. If the database class
* `\ECRE\Ecre_Database` exists, it fetches the user's custom settings from the database and merges them with the global
* settings, with the user's settings overriding the global ones. If an error occurs while fetching custom settings,
* the global settings are returned.
*
* @since 1.0.0
*
* @param array $global_settings The global settings array to be merged.
* @param int $user_id The ID of the user whose custom settings should be merged (optional).
*
* @return array The merged settings array, with custom settings overriding the global ones.
*/
function ecre_merge_with_custom_settings( $global_settings, $user_id = null ) {
// If no user ID, return global as-is.
if ( empty( $user_id ) ) {
return $global_settings;
}
// If database class doesn't exist, return global settings.
if ( ! class_exists( '\ECRE\Ecre_Database' ) ) {
return $global_settings;
}
try {
$database = new \ECRE\Ecre_Database();
$custom_settings = $database->get_user_custom_settings( $user_id );
// If no custom settings, return global as-is.
if ( empty( $custom_settings ) ) {
return $global_settings;
}
// Merge: custom settings override global.
return array_merge( $global_settings, $custom_settings );
} catch ( Exception $e ) {
return $global_settings;
}
}
}
}