6281 lines
253 KiB
PHP
6281 lines
253 KiB
PHP
<?php
|
||
/**
|
||
* Main class for Smart Coupons
|
||
*
|
||
* @author StoreApps
|
||
* @since 3.3.0
|
||
* @version 5.4.1
|
||
*
|
||
* @package woocommerce-smart-coupons/includes/
|
||
*/
|
||
|
||
if ( ! defined( 'ABSPATH' ) ) {
|
||
exit; // Exit if accessed directly.
|
||
}
|
||
|
||
if ( ! class_exists( 'WC_Smart_Coupons' ) ) {
|
||
|
||
/**
|
||
* Main WooCommerce Smart Coupons Class.
|
||
*
|
||
* @return object of WC_Smart_Coupons having all functionality of Smart Coupons
|
||
*/
|
||
class WC_Smart_Coupons {
|
||
|
||
/**
|
||
* Text Domain
|
||
*
|
||
* @var $text_domain
|
||
*/
|
||
public static $text_domain = 'woocommerce-smart-coupons';
|
||
|
||
/**
|
||
* Text Domain
|
||
*
|
||
* @var $text_domain
|
||
*/
|
||
public $plugin_data = array();
|
||
|
||
/**
|
||
* Variable to hold instance of Smart Coupons
|
||
*
|
||
* @var $instance
|
||
*/
|
||
private static $instance = null;
|
||
|
||
/**
|
||
* Get single instance of Smart Coupons.
|
||
*
|
||
* @return WC_Smart_Coupons Singleton object of WC_Smart_Coupons
|
||
*/
|
||
public static function get_instance() {
|
||
|
||
// Check if instance is already exists.
|
||
if ( is_null( self::$instance ) ) {
|
||
self::$instance = new self();
|
||
}
|
||
|
||
return self::$instance;
|
||
}
|
||
|
||
/**
|
||
* Cloning is forbidden.
|
||
*
|
||
* @since 3.3.0
|
||
*/
|
||
private function __clone() {
|
||
wc_doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?', 'woocommerce-smart-coupons' ), '3.3.0' );
|
||
}
|
||
|
||
/**
|
||
* Constructor
|
||
*/
|
||
private function __construct() {
|
||
|
||
$this->includes();
|
||
|
||
add_action( 'plugins_loaded', array( $this, 'load_action_scheduler' ), -1 );
|
||
|
||
add_action( 'init', array( $this, 'process_activation' ) );
|
||
add_action( 'init', array( $this, 'add_sc_options' ) );
|
||
add_action( 'init', array( $this, 'define_label_for_store_credit' ) );
|
||
|
||
add_filter( 'woocommerce_coupon_is_valid', array( $this, 'is_smart_coupon_valid' ), 10, 3 );
|
||
add_filter( 'woocommerce_coupon_is_valid', array( $this, 'is_user_usage_limit_valid' ), 10, 3 );
|
||
add_filter( 'woocommerce_coupon_is_valid_for_product', array( $this, 'smart_coupons_is_valid_for_product' ), 10, 4 );
|
||
add_filter( 'woocommerce_coupon_validate_expiry_date', array( $this, 'validate_expiry_time' ), 999, 3 );
|
||
add_filter( 'woocommerce_apply_individual_use_coupon', array( $this, 'smart_coupons_override_individual_use' ), 10, 3 );
|
||
add_filter( 'woocommerce_apply_with_individual_use_coupon', array( $this, 'smart_coupons_override_with_individual_use' ), 10, 4 );
|
||
|
||
add_action( 'restrict_manage_posts', array( $this, 'woocommerce_restrict_manage_smart_coupons' ), 20 );
|
||
add_action( 'admin_init', array( $this, 'woocommerce_export_coupons' ) );
|
||
|
||
add_action( 'personal_options_update', array( $this, 'my_profile_update' ) );
|
||
add_action( 'edit_user_profile_update', array( $this, 'my_profile_update' ) );
|
||
|
||
add_filter( 'generate_smart_coupon_action', array( $this, 'generate_smart_coupon_action' ), 1, 10 );
|
||
|
||
add_action( 'wc_sc_new_coupon_generated', array( $this, 'smart_coupons_plugin_used' ) );
|
||
|
||
// Actions used to insert a new endpoint in the WordPress.
|
||
add_action( 'init', array( $this, 'sc_add_endpoints' ), 11 );
|
||
|
||
add_action( 'admin_enqueue_scripts', array( $this, 'smart_coupon_styles_and_scripts' ), 20 );
|
||
add_action( 'admin_enqueue_scripts', array( $this, 'register_plugin_styles' ) );
|
||
add_action( 'wp_enqueue_scripts', array( $this, 'register_plugin_styles' ) );
|
||
|
||
add_filter( 'wc_smart_coupons_export_headers', array( $this, 'wc_smart_coupons_export_headers' ) );
|
||
add_filter( 'woocommerce_email_footer_text', array( $this, 'email_footer_replace_site_title' ) );
|
||
|
||
add_filter( 'is_protected_meta', array( $this, 'make_sc_meta_protected' ), 10, 3 );
|
||
|
||
add_action( 'admin_notices', array( $this, 'minimum_woocommerce_version_requirement' ) );
|
||
|
||
add_action( 'wp_loaded', array( $this, 'sc_handle_store_credit_application' ), 15 );
|
||
|
||
add_filter( 'woocommerce_debug_tools', array( $this, 'clear_cache_tool' ) );
|
||
|
||
add_action( 'woocommerce_checkout_update_order_review', array( $this, 'woocommerce_checkout_update_order_review' ) );
|
||
|
||
add_action( 'woocommerce_cart_reset', array( $this, 'woocommerce_cart_reset' ) );
|
||
|
||
// Actions used to schedule sending of coupons.
|
||
add_action( 'wc_sc_send_scheduled_coupon_email', array( $this, 'send_scheduled_coupon_email' ), 10, 7 );
|
||
add_action( 'publish_future_post', array( $this, 'process_published_scheduled_coupon' ) );
|
||
add_action( 'before_delete_post', array( $this, 'delete_scheduled_coupon_actions' ) );
|
||
add_action( 'admin_footer', array( $this, 'enqueue_admin_footer_scripts' ) );
|
||
add_action( 'wp_ajax_wc_sc_check_scheduled_coupon_actions', array( $this, 'check_scheduled_coupon_actions' ) );
|
||
|
||
// Filter to modify discount amount for percentage type coupon.
|
||
add_filter( 'woocommerce_coupon_get_discount_amount', array( $this, 'get_coupon_discount_amount' ), 10, 5 );
|
||
|
||
// Filter to add default values to coupon meta fields.
|
||
add_filter( 'smart_coupons_parser_postmeta_defaults', array( $this, 'postmeta_defaults' ) );
|
||
|
||
// Filter to register Smart Coupons' email classes.
|
||
add_filter( 'woocommerce_email_classes', array( $this, 'register_email_classes' ) );
|
||
|
||
add_filter( 'woocommerce_hold_stock_for_checkout', array( $this, 'hold_stock_for_checkout' ) );
|
||
|
||
add_action( 'wc_sc_generate_coupon', array( $this, 'generate_coupon' ) );
|
||
add_action( 'wc_sc_paint_coupon', array( $this, 'paint_coupon' ) );
|
||
|
||
add_filter( 'woocommerce_rest_api_get_rest_namespaces', array( $this, 'rest_namespace' ) );
|
||
|
||
add_filter( 'woocommerce_shipping_free_shipping_is_available', array( $this, 'is_eligible_for_free_shipping' ), 10, 3 );
|
||
|
||
add_action( 'woocommerce_system_status_report', array( $this, 'smart_coupons_system_status_report' ), 11 );
|
||
|
||
add_action( 'woocommerce_rest_prepare_shop_order_object', array( $this, 'rest_api_prepare_shop_order_object' ), 10, 3 );
|
||
|
||
add_action( 'before_woocommerce_init', array( $this, 'hpos_compat_declaration' ) );
|
||
|
||
}
|
||
|
||
/**
|
||
* Function to handle WC compatibility related function call from appropriate class
|
||
*
|
||
* @param string $function_name Function to call.
|
||
* @param array $arguments Array of arguments passed while calling $function_name.
|
||
* @return mixed Result of function call.
|
||
*/
|
||
public function __call( $function_name, $arguments = array() ) {
|
||
|
||
if ( ! is_callable( 'SA_WC_Compatibility_4_4', $function_name ) ) {
|
||
return;
|
||
}
|
||
|
||
if ( ! empty( $arguments ) ) {
|
||
return call_user_func_array( 'SA_WC_Compatibility_4_4::' . $function_name, $arguments );
|
||
} else {
|
||
return call_user_func( 'SA_WC_Compatibility_4_4::' . $function_name );
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Include files
|
||
*/
|
||
public function includes() {
|
||
|
||
include_once 'compat/class-sa-wc-compatibility-4-4.php';
|
||
include_once 'compat/class-wc-sc-wpml-compatibility.php';
|
||
include_once 'compat/class-wcopc-sc-compatibility.php';
|
||
include_once 'compat/class-wcs-sc-compatibility.php';
|
||
include_once 'compat/class-wc-sc-wmc-compatibility.php';
|
||
include_once 'compat/class-wc-sc-aelia-cs-compatibility.php';
|
||
include_once 'compat/class-wc-sc-kco-compatibility.php';
|
||
|
||
include_once 'class-wc-sc-admin-welcome.php';
|
||
include_once 'class-wc-sc-background-coupon-importer.php';
|
||
include_once 'class-wc-sc-admin-pages.php';
|
||
include_once 'class-wc-sc-admin-notifications.php';
|
||
|
||
include_once 'class-wc-sc-ajax.php';
|
||
include_once 'class-wc-sc-display-coupons.php';
|
||
|
||
include_once 'class-wc-sc-settings.php';
|
||
include_once 'class-wc-sc-shortcode.php';
|
||
include_once 'class-wc-sc-purchase-credit.php';
|
||
include_once 'class-wc-sc-url-coupon.php';
|
||
include_once 'class-wc-sc-print-coupon.php';
|
||
include_once 'class-wc-sc-coupon-fields.php';
|
||
include_once 'class-wc-sc-auto-apply-coupon.php';
|
||
include_once 'class-wc-sc-product-fields.php';
|
||
include_once 'class-wc-sc-order-fields.php';
|
||
include_once 'class-wc-sc-coupon-process.php';
|
||
include_once 'class-wc-sc-global-coupons.php';
|
||
include_once 'class-wc-sc-admin-coupons-dashboard-actions.php';
|
||
include_once 'class-wc-sc-privacy.php';
|
||
include_once 'class-wc-sc-coupon-actions.php';
|
||
include_once 'class-wc-sc-coupon-columns.php';
|
||
include_once 'class-wc-sc-coupons-by-location.php';
|
||
include_once 'class-wc-sc-coupons-by-payment-method.php';
|
||
include_once 'class-wc-sc-coupons-by-shipping-method.php';
|
||
include_once 'class-wc-sc-coupons-by-user-role.php';
|
||
include_once 'class-wc-sc-coupons-by-product-attribute.php';
|
||
include_once 'class-wc-sc-coupons-by-taxonomy.php';
|
||
include_once 'class-wc-sc-coupons-by-excluded-email.php';
|
||
include_once 'class-wc-sc-coupon-message.php';
|
||
include_once 'class-wc-sc-coupon-categories.php';
|
||
include_once 'class-wc-sc-coupons-by-product-quantity.php';
|
||
include_once 'class-wc-sc-coupon-refund-process.php';
|
||
include_once 'class-wc-sc-background-upgrade.php';
|
||
include_once 'blocks/class-wc-sc-gutenberg-coupon-block.php';
|
||
|
||
}
|
||
|
||
/**
|
||
* Process activation of the plugin
|
||
*/
|
||
public function process_activation() {
|
||
|
||
if ( ! get_transient( '_smart_coupons_process_activation' ) ) {
|
||
return;
|
||
}
|
||
|
||
delete_transient( '_smart_coupons_process_activation' );
|
||
|
||
include_once 'class-wc-sc-act-deact.php';
|
||
|
||
WC_SC_Act_Deact::process_activation();
|
||
|
||
}
|
||
|
||
/**
|
||
* Load action scheduler
|
||
*/
|
||
public function load_action_scheduler() {
|
||
if ( ! class_exists( 'ActionScheduler' ) ) {
|
||
include_once 'libraries/action-scheduler/action-scheduler.php';
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set options
|
||
*/
|
||
public function add_sc_options() {
|
||
|
||
$this->plugin_data = self::get_smart_coupons_plugin_data();
|
||
|
||
add_option( 'woocommerce_delete_smart_coupon_after_usage', 'no', '', 'no' );
|
||
add_option( 'woocommerce_smart_coupon_apply_before_tax', 'no', '', 'no' );
|
||
add_option( 'woocommerce_smart_coupon_include_tax', 'no', '', 'no' );
|
||
add_option( 'woocommerce_smart_coupon_show_my_account', 'yes', '', 'no' );
|
||
add_option( 'smart_coupons_is_show_associated_coupons', 'no', '', 'no' );
|
||
add_option( 'smart_coupons_show_coupon_description', 'no', '', 'no' );
|
||
add_option( 'smart_coupons_is_send_email', 'yes', '', 'no' );
|
||
add_option( 'smart_coupons_is_print_coupon', 'yes', '', 'no' );
|
||
add_option( 'show_coupon_received_on_my_account', 'no', '', 'no' );
|
||
add_option( 'pay_from_smart_coupon_of_original_order', 'yes', '', 'no' );
|
||
add_option( 'stop_recursive_coupon_generation', 'no', '', 'no' );
|
||
add_option( 'sc_gift_certificate_shop_loop_button_text', __( 'Select options', 'woocommerce-smart-coupons' ), '', 'no' );
|
||
add_option( 'wc_sc_setting_max_coupon_to_show', '5', '', 'no' );
|
||
add_option( 'smart_coupons_show_invalid_coupons_on_myaccount', 'no', '', 'no' );
|
||
add_option( 'smart_coupons_sell_store_credit_at_less_price', 'no', '', 'no' );
|
||
add_option( 'smart_coupons_display_coupon_receiver_details_form', 'yes', '', 'no' );
|
||
|
||
// Convert SC admin email settings into WC email settings.
|
||
$is_send_email = get_option( 'smart_coupons_is_send_email' );
|
||
if ( false !== $is_send_email ) {
|
||
$coupon_email_settings = get_option( 'woocommerce_wc_sc_email_coupon_settings' );
|
||
if ( false === $coupon_email_settings ) {
|
||
$coupon_email_settings = array();
|
||
$coupon_email_settings['enabled'] = $is_send_email;
|
||
update_option( 'woocommerce_wc_sc_email_coupon_settings', $coupon_email_settings, 'no' );
|
||
}
|
||
}
|
||
|
||
$is_combine_email = get_option( 'smart_coupons_combine_emails' );
|
||
if ( false !== $is_combine_email ) {
|
||
$combine_email_settings = get_option( 'woocommerce_wc_sc_combined_email_coupon_settings' );
|
||
if ( false === $combine_email_settings ) {
|
||
$combine_email_settings = array();
|
||
$combine_email_settings['enabled'] = $is_combine_email;
|
||
update_option( 'woocommerce_wc_sc_combined_email_coupon_settings', $combine_email_settings, 'no' );
|
||
}
|
||
}
|
||
|
||
$valid_designs = $this->get_valid_coupon_designs();
|
||
|
||
$coupon_design = get_option( 'wc_sc_setting_coupon_design' );
|
||
if ( false === $coupon_design ) {
|
||
add_option( 'wc_sc_setting_coupon_design', 'basic', '', 'no' );
|
||
} else {
|
||
if ( 'custom-design' !== $coupon_design && ! in_array( $coupon_design, $valid_designs, true ) ) {
|
||
update_option( 'wc_sc_setting_coupon_design', 'basic', 'no' );
|
||
}
|
||
}
|
||
|
||
$coupon_background_color = get_option( 'wc_sc_setting_coupon_background_color' );
|
||
if ( false === $coupon_background_color ) {
|
||
add_option( 'wc_sc_setting_coupon_background_color', '#2b2d42', '', 'no' );
|
||
} else {
|
||
add_option( 'wc_sc_setting_coupon_third_color', $coupon_background_color, '', 'no' );
|
||
}
|
||
|
||
$coupon_foreground_color = get_option( 'wc_sc_setting_coupon_foreground_color' );
|
||
if ( false === $coupon_foreground_color ) {
|
||
add_option( 'wc_sc_setting_coupon_foreground_color', '#edf2f4', '', 'no' );
|
||
}
|
||
|
||
$coupon_third_color = get_option( 'wc_sc_setting_coupon_third_color' );
|
||
if ( false === $coupon_third_color ) {
|
||
add_option( 'wc_sc_setting_coupon_third_color', '#d90429', '', 'no' );
|
||
}
|
||
|
||
$coupon_design_colors = get_option( 'wc_sc_setting_coupon_design_colors' );
|
||
if ( false === $coupon_design_colors ) {
|
||
if ( false !== $coupon_background_color && false !== $coupon_foreground_color ) {
|
||
add_option( 'wc_sc_setting_coupon_design_colors', 'custom', '', 'no' );
|
||
} else {
|
||
add_option( 'wc_sc_setting_coupon_design_colors', '2b2d42-edf2f4-d90429', '', 'no' );
|
||
}
|
||
}
|
||
|
||
$coupon_design_for_email = get_option( 'wc_sc_setting_coupon_design_for_email' );
|
||
if ( false === $coupon_design_for_email ) {
|
||
add_option( 'wc_sc_setting_coupon_design_for_email', 'email-coupon', '', 'no' );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Function to log messages generated by Smart Coupons plugin
|
||
*
|
||
* @param string $level Message type. Valid values: debug, info, notice, warning, error, critical, alert, emergency.
|
||
* @param string $message The message to log.
|
||
*/
|
||
public function log( $level = 'notice', $message = '' ) {
|
||
|
||
if ( empty( $message ) ) {
|
||
return;
|
||
}
|
||
|
||
if ( function_exists( 'wc_get_logger' ) ) {
|
||
$logger = wc_get_logger();
|
||
$context = array( 'source' => 'woocommerce-smart-coupons' );
|
||
$logger->log( $level, $message, $context );
|
||
} else {
|
||
include_once plugin_dir_path( WC_PLUGIN_FILE ) . 'includes/class-wc-logger.php';
|
||
$logger = new WC_Logger();
|
||
$logger->add( 'woocommerce-smart-coupons', $message );
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Coupon's expiration date (formatted)
|
||
*
|
||
* @param int $expiry_date Expiry date of coupon.
|
||
* @return string $expires_string Formatted expiry date
|
||
*/
|
||
public function get_expiration_format( $expiry_date ) {
|
||
|
||
if ( $this->is_wc_gte_30() && $expiry_date instanceof WC_DateTime ) {
|
||
$expiry_date = ( is_callable( array( $expiry_date, 'getTimestamp' ) ) ) ? $expiry_date->getTimestamp() : null;
|
||
} elseif ( ! is_int( $expiry_date ) ) {
|
||
$expiry_date = strtotime( $expiry_date );
|
||
}
|
||
|
||
$expiry_date += $this->wc_timezone_offset();
|
||
|
||
$expires_string = date_i18n( get_option( 'date_format', 'd-M-Y' ), $expiry_date );
|
||
|
||
return apply_filters(
|
||
'wc_sc_formatted_coupon_expiry_date',
|
||
$expires_string,
|
||
array(
|
||
'source' => $this,
|
||
'expiry_date' => $expiry_date,
|
||
)
|
||
);
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* Function to send e-mail containing coupon code to receiver
|
||
*
|
||
* @param array $coupon_title Associative array containing receiver's details.
|
||
* @param string $discount_type Type of coupon.
|
||
* @param int $order_id Associated order id.
|
||
* @param array $gift_certificate_receiver_name Array of receiver's name.
|
||
* @param string $message_from_sender Message added by sender.
|
||
* @param string $gift_certificate_sender_name Sender name.
|
||
* @param string $gift_certificate_sender_email Sender email.
|
||
* @param boolean $is_gift Whether it is a gift certificate or store credit.
|
||
*/
|
||
public function sa_email_coupon( $coupon_title, $discount_type, $order_id = '', $gift_certificate_receiver_name = '', $message_from_sender = '', $gift_certificate_sender_name = '', $gift_certificate_sender_email = '', $is_gift = '' ) {
|
||
|
||
$is_send_email = $this->is_email_template_enabled();
|
||
$combine_emails = $this->is_email_template_enabled( 'combine' );
|
||
|
||
if ( 'yes' === $is_send_email ) {
|
||
WC()->mailer();
|
||
}
|
||
|
||
$is_send_email = apply_filters(
|
||
'wc_sc_is_send_coupon_email',
|
||
$is_send_email,
|
||
array(
|
||
'source' => $this,
|
||
'coupon_title' => $coupon_title,
|
||
'discount_type' => $discount_type,
|
||
'order_id' => $order_id,
|
||
'gift_certificate_receiver_name' => $gift_certificate_receiver_name,
|
||
'message_from_sender' => $message_from_sender,
|
||
'gift_certificate_sender_name' => $gift_certificate_sender_name,
|
||
'gift_certificate_sender_email' => $gift_certificate_sender_email,
|
||
'is_gift' => $is_gift,
|
||
)
|
||
);
|
||
|
||
$order = ( ! empty( $order_id ) ) ? wc_get_order( $order_id ) : null;
|
||
|
||
foreach ( $coupon_title as $email => $coupon ) {
|
||
|
||
if ( empty( $email ) ) {
|
||
$email = $gift_certificate_sender_email;
|
||
}
|
||
|
||
$amount = $coupon['amount'];
|
||
$coupon_code = strtolower( $coupon['code'] );
|
||
|
||
if ( ! empty( $order_id ) ) {
|
||
$coupon_receiver_details = $this->get_post_meta( $order_id, 'sc_coupon_receiver_details', true, false, $order );
|
||
if ( ! is_array( $coupon_receiver_details ) || empty( $coupon_receiver_details ) ) {
|
||
$coupon_receiver_details = array();
|
||
}
|
||
$coupon_receiver_details[] = array(
|
||
'code' => $coupon_code,
|
||
'amount' => $amount,
|
||
'email' => $email,
|
||
'message' => $message_from_sender,
|
||
);
|
||
$this->update_post_meta( $order_id, 'sc_coupon_receiver_details', $coupon_receiver_details, false, $order );
|
||
}
|
||
|
||
$action_args = apply_filters(
|
||
'wc_sc_email_coupon_notification_args',
|
||
array(
|
||
'order_id' => $order_id,
|
||
'email' => $email,
|
||
'coupon' => $coupon,
|
||
'discount_type' => $discount_type,
|
||
'receiver_name' => $gift_certificate_receiver_name,
|
||
'message_from_sender' => $message_from_sender,
|
||
'gift_certificate_sender_name' => $gift_certificate_sender_name,
|
||
'gift_certificate_sender_email' => $gift_certificate_sender_email,
|
||
'is_gift' => $is_gift,
|
||
)
|
||
);
|
||
|
||
$schedule_gift_sending = 'no';
|
||
if ( ! empty( $order_id ) ) {
|
||
$schedule_gift_sending = ( $this->is_callable( $order, 'get_meta' ) ) ? $order->get_meta( 'wc_sc_schedule_gift_sending' ) : $this->get_post_meta( $order_id, 'wc_sc_schedule_gift_sending', true );
|
||
}
|
||
|
||
$is_schedule_gift_sending = 'no';
|
||
if ( 'yes' === $schedule_gift_sending ) {
|
||
$coupon_id = wc_get_coupon_id_by_code( $coupon_code );
|
||
$coupon_receiver_details = $this->get_post_meta( $coupon_id, 'wc_sc_coupon_receiver_details', true );
|
||
$scheduled_coupon_code = ( ! empty( $coupon_receiver_details['coupon_details']['code'] ) ) ? strtolower( $coupon_receiver_details['coupon_details']['code'] ) : '';
|
||
if ( $scheduled_coupon_code === $coupon_code ) {
|
||
$is_schedule_gift_sending = 'yes';
|
||
}
|
||
}
|
||
|
||
if ( 'yes' === $is_send_email && ( 'no' === $combine_emails || 'yes' === $is_schedule_gift_sending ) ) {
|
||
// Trigger email notification.
|
||
do_action( 'wc_sc_email_coupon_notification', $action_args );
|
||
if ( 'yes' === $is_schedule_gift_sending ) {
|
||
// Delete receiver detail post meta as it is no longer necessary.
|
||
$this->delete_post_meta( $coupon_id, 'wc_sc_coupon_receiver_details' );
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Function to send combined e-mail containing coupon codes to receiver
|
||
*
|
||
* @param string $receiver_email receiver's email.
|
||
* @param array $receiver_details receiver details(code,message etc).
|
||
* @param int $order_id Associated order id.
|
||
* @param string $gift_certificate_sender_name Sender name.
|
||
* @param string $gift_certificate_sender_email Sender email.
|
||
*/
|
||
public function send_combined_coupon_email( $receiver_email = '', $receiver_details = array(), $order_id = 0, $gift_certificate_sender_name = '', $gift_certificate_sender_email = '' ) {
|
||
|
||
$is_send_email = $this->is_email_template_enabled();
|
||
$combine_emails = $this->is_email_template_enabled( 'combine' );
|
||
|
||
if ( 'yes' === $is_send_email && 'yes' === $combine_emails ) {
|
||
WC()->mailer();
|
||
|
||
$order = ( ! empty( $order_id ) ) ? wc_get_order( $order_id ) : null;
|
||
|
||
$is_gift = '';
|
||
if ( ! empty( $order_id ) ) {
|
||
$is_gift = $this->get_post_meta( $order_id, 'is_gift', true );
|
||
}
|
||
|
||
if ( count( $receiver_details ) === 1 ) {
|
||
$coupon_code = ( ! empty( $receiver_details[0]['code'] ) ) ? $receiver_details[0]['code'] : '';
|
||
$message_from_sender = ( ! empty( $receiver_details[0]['message'] ) ) ? $receiver_details[0]['message'] : '';
|
||
|
||
$coupon = new WC_Coupon( $coupon_code );
|
||
$coupon_amount = $this->get_amount( $coupon, true, $order );
|
||
$discount_type = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
|
||
$coupon_data = $this->get_coupon_meta_data( $coupon );
|
||
|
||
$coupon_detail = array(
|
||
'amount' => $coupon_amount,
|
||
'code' => $coupon_code,
|
||
);
|
||
|
||
$action_args = apply_filters(
|
||
'wc_sc_email_coupon_notification_args',
|
||
array(
|
||
'order_id' => $order_id,
|
||
'email' => $receiver_email,
|
||
'coupon' => $coupon_detail,
|
||
'discount_type' => $discount_type,
|
||
'receiver_name' => '',
|
||
'message_from_sender' => $message_from_sender,
|
||
'gift_certificate_sender_name' => $gift_certificate_sender_name,
|
||
'gift_certificate_sender_email' => $gift_certificate_sender_email,
|
||
'is_gift' => $is_gift,
|
||
)
|
||
);
|
||
// Trigger single email notification.
|
||
do_action( 'wc_sc_email_coupon_notification', $action_args );
|
||
return;
|
||
}
|
||
|
||
$action_args = apply_filters(
|
||
'wc_sc_email_coupon_notification_args',
|
||
array(
|
||
'order_id' => $order_id,
|
||
'email' => $receiver_email,
|
||
'receiver_details' => $receiver_details,
|
||
'gift_certificate_sender_name' => $gift_certificate_sender_name,
|
||
'gift_certificate_sender_email' => $gift_certificate_sender_email,
|
||
'is_gift' => $is_gift,
|
||
)
|
||
);
|
||
|
||
// Trigger combined email notification.
|
||
do_action( 'wc_sc_combined_email_coupon_notification', $action_args );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Function to schedule e-mail sending process containing coupon code to customer
|
||
*
|
||
* @param array $action_args arguments for Action Scheduler.
|
||
* @param string $sending_timestamp timestamp for scheduling email.
|
||
* @return boolean email sending scheduled or not.
|
||
*/
|
||
public function schedule_coupon_email( $action_args = array(), $sending_timestamp = '' ) {
|
||
|
||
if ( empty( $action_args ) || empty( $sending_timestamp ) ) {
|
||
return false;
|
||
}
|
||
|
||
$coupon_id = 0;
|
||
if ( isset( $action_args['coupon_id'] ) && ! empty( $action_args['coupon_id'] ) ) {
|
||
$coupon_id = $action_args['coupon_id'];
|
||
}
|
||
|
||
$ref_key = '';
|
||
if ( isset( $action_args['ref_key'] ) && ! empty( $action_args['ref_key'] ) ) {
|
||
$ref_key = $action_args['ref_key'];
|
||
}
|
||
|
||
if ( ! empty( $coupon_id ) && ! empty( $ref_key ) && function_exists( 'as_schedule_single_action' ) ) {
|
||
$actions_id = as_schedule_single_action( $sending_timestamp, 'wc_sc_send_scheduled_coupon_email', $action_args );
|
||
if ( $actions_id ) {
|
||
$scheduled_actions_ids = $this->get_post_meta( $coupon_id, 'wc_sc_scheduled_actions_ids', true );
|
||
if ( empty( $scheduled_actions_ids ) || ! is_array( $scheduled_actions_ids ) ) {
|
||
$scheduled_actions_ids = array();
|
||
}
|
||
$scheduled_actions_ids[ $ref_key ] = $actions_id;
|
||
// Stored actions ids in coupons so that we can delete them when coupon gets deleted or email is sent successfully.
|
||
$this->update_post_meta( $coupon_id, 'wc_sc_scheduled_actions_ids', $scheduled_actions_ids );
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Function to send scheduled coupon's e-mail containing coupon code to receiver. It is triggered through Action Scheduler
|
||
*
|
||
* @param string $auto_generate is auto generated coupon.
|
||
* @param int $coupon_id Associated coupon id.
|
||
* @param int $parent_id Associated parent coupon id.
|
||
* @param int $order_id Associated order id.
|
||
* @param string $receiver_email receiver email.
|
||
* @param string $sender_message_index_key key containing index of sender's message from gift_receiver_message meta in order.
|
||
* @param string $ref_key timestamp based reference key.
|
||
*/
|
||
public function send_scheduled_coupon_email( $auto_generate = '', $coupon_id = '', $parent_id = '', $order_id = '', $receiver_email = '', $sender_message_index_key = '', $ref_key = '' ) {
|
||
|
||
if ( ! empty( $coupon_id ) && ! empty( $order_id ) && ! empty( $receiver_email ) ) {
|
||
|
||
$coupon = new WC_Coupon( $coupon_id );
|
||
|
||
$coupon_status = ( $this->is_callable( $coupon, 'get_status' ) ) ? $coupon->get_status() : get_post_status( $coupon_id );
|
||
if ( 'publish' !== $coupon_status ) {
|
||
return;
|
||
}
|
||
|
||
$order = wc_get_order( $order_id );
|
||
if ( is_a( $coupon, 'WC_Coupon' ) && is_a( $order, 'WC_Order' ) ) {
|
||
$is_callable_order_get_meta = $this->is_callable( $order, 'get_meta' );
|
||
$is_callable_coupon_get_meta = $this->is_callable( $coupon, 'get_meta' );
|
||
$is_callable_coupon_update_meta_data = $this->is_callable( $coupon, 'update_meta_data' );
|
||
$sc_disable_email_restriction = $this->get_post_meta( $parent_id, 'sc_disable_email_restriction', true );
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$discount_type = $coupon->get_discount_type();
|
||
$coupon_code = $coupon->get_code();
|
||
} else {
|
||
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
|
||
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
|
||
}
|
||
|
||
$coupon_amount = $this->get_amount( $coupon, true, $order );
|
||
|
||
$coupon_details = array(
|
||
$receiver_email => array(
|
||
'parent' => $parent_id,
|
||
'code' => $coupon_code,
|
||
'amount' => $coupon_amount,
|
||
),
|
||
);
|
||
|
||
$receiver_name = '';
|
||
$message_from_sender = '';
|
||
$gift_certificate_sender_name = '';
|
||
$gift_certificate_sender_email = '';
|
||
|
||
$is_gift = ( true === $is_callable_order_get_meta ) ? $order->get_meta( 'is_gift' ) : $this->get_post_meta( $order_id, 'is_gift', true );
|
||
|
||
// In case of auto generated coupons receiver's details are saved in generated coupon.
|
||
if ( 'yes' === $auto_generate ) {
|
||
$coupon_receiver_details = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'wc_sc_coupon_receiver_details' ) : $this->get_post_meta( $coupon_id, 'wc_sc_coupon_receiver_details', true );
|
||
if ( ! empty( $coupon_receiver_details ) && is_array( $coupon_receiver_details ) ) {
|
||
$message_from_sender = $coupon_receiver_details['message_from_sender'];
|
||
$gift_certificate_sender_name = $coupon_receiver_details['gift_certificate_sender_name'];
|
||
$gift_certificate_sender_email = $coupon_receiver_details['gift_certificate_sender_email'];
|
||
}
|
||
} else {
|
||
$receivers_messages = ( true === $is_callable_order_get_meta ) ? $order->get_meta( 'gift_receiver_message' ) : $this->get_post_meta( $order_id, 'gift_receiver_message', true );
|
||
if ( strpos( $sender_message_index_key, ':' ) > 0 ) {
|
||
$index_keys = explode( ':', $sender_message_index_key );
|
||
$coupon_index = $index_keys[0];
|
||
$message_index = $index_keys[1];
|
||
if ( isset( $receivers_messages[ $coupon_index ][ $message_index ] ) ) {
|
||
$message_from_sender = $receivers_messages[ $coupon_index ][ $message_index ];
|
||
}
|
||
}
|
||
}
|
||
|
||
$this->sa_email_coupon( $coupon_details, $discount_type, $order_id, $receiver_name, $message_from_sender, $gift_certificate_sender_name, $gift_certificate_sender_email, $is_gift );
|
||
|
||
if ( ( 'no' === $sc_disable_email_restriction || empty( $sc_disable_email_restriction ) ) ) {
|
||
$old_customers_email_ids = (array) maybe_unserialize( ( $this->is_callable( $coupon, 'get_email_restrictions' ) ) ? $coupon->get_email_restrictions() : $this->get_post_meta( $coupon_id, 'customer_email', true ) );
|
||
$old_customers_email_ids[] = $receiver_email;
|
||
if ( true === $is_callable_coupon_update_meta_data ) {
|
||
$coupon->set_email_restrictions( $old_customers_email_ids );
|
||
} else {
|
||
update_post_meta( $coupon_id, 'customer_email', $old_customers_email_ids );
|
||
}
|
||
}
|
||
|
||
if ( ! empty( $ref_key ) ) {
|
||
$scheduled_actions_ids = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'wc_sc_scheduled_actions_ids' ) : $this->get_post_meta( $coupon_id, 'wc_sc_scheduled_actions_ids', true );
|
||
if ( isset( $scheduled_actions_ids[ $ref_key ] ) ) {
|
||
unset( $scheduled_actions_ids[ $ref_key ] );
|
||
}
|
||
if ( ! empty( $scheduled_actions_ids ) ) {
|
||
if ( true === $is_callable_coupon_update_meta_data ) {
|
||
$coupon->update_meta_data( 'wc_sc_scheduled_actions_ids', $scheduled_actions_ids );
|
||
} else {
|
||
update_post_meta( $coupon_id, 'wc_sc_scheduled_actions_ids', $scheduled_actions_ids );
|
||
}
|
||
} else {
|
||
// Delete scheduled action ids meta since it is empty now.
|
||
$this->delete_post_meta( $coupon_id, 'wc_sc_scheduled_actions_ids', null, $coupon );
|
||
}
|
||
}
|
||
if ( $this->is_callable( $coupon, 'save' ) ) {
|
||
$coupon->save();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Function to process scheduled coupons.
|
||
*
|
||
* @param int $coupon_id published coupon's id.
|
||
*/
|
||
public function process_published_scheduled_coupon( $coupon_id = 0 ) {
|
||
|
||
$post_type = get_post_type( $coupon_id );
|
||
if ( 'shop_coupon' !== $post_type ) {
|
||
return false;
|
||
}
|
||
|
||
$coupon = new WC_Coupon( $coupon_id );
|
||
if ( is_a( $coupon, 'WC_Coupon' ) ) {
|
||
$is_callable_coupon_get_meta = $this->is_callable( $coupon, 'get_meta' );
|
||
$order_id = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'generated_from_order_id' ) : $this->get_post_meta( $coupon_id, 'generated_from_order_id', true );
|
||
$order = wc_get_order( $order_id );
|
||
if ( is_a( $order, 'WC_Order' ) ) {
|
||
$coupon_receiver_details = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'wc_sc_coupon_receiver_details' ) : $this->get_post_meta( $coupon_id, 'wc_sc_coupon_receiver_details', true );
|
||
if ( ! empty( $coupon_receiver_details ) && is_array( $coupon_receiver_details ) ) {
|
||
$parent_id = $coupon_receiver_details['coupon_details']['parent'];
|
||
$receiver_email = $coupon_receiver_details['gift_certificate_receiver_email'];
|
||
$gift_certificate_sender_name = $coupon_receiver_details['gift_certificate_sender_name'];
|
||
$gift_certificate_sender_email = $coupon_receiver_details['gift_certificate_sender_email'];
|
||
$sending_timestamp = get_post_time( 'U', true, $coupon_id ); // Get coupon publish timestamp.
|
||
$action_args = array(
|
||
'auto_generate' => 'yes',
|
||
'coupon_id' => $coupon_id,
|
||
'parent_id' => $parent_id, // Parent coupon id.
|
||
'order_id' => $order_id,
|
||
'receiver_email' => $receiver_email,
|
||
'message_index_key' => '',
|
||
'ref_key' => uniqid(), // A unique timestamp key to relate action schedulers with their coupons.
|
||
);
|
||
$is_scheduled = $this->schedule_coupon_email( $action_args, $sending_timestamp );
|
||
if ( ! $is_scheduled ) {
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$coupon_code = $coupon->get_code();
|
||
} else {
|
||
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
|
||
}
|
||
/* translators: 1. Receiver email 2. Coupon code 3. Order id */
|
||
$this->log( 'error', sprintf( __( 'Failed to schedule email to "%1$s" for coupon "%2$s" received from order #%3$s.', 'woocommerce-smart-coupons' ), $receiver_email, $coupon_code, $order_id ) );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Function to delete action schedulers when associated coupon is deleted.
|
||
*
|
||
* @param int $coupon_id coupon id.
|
||
*/
|
||
public function delete_scheduled_coupon_actions( $coupon_id = 0 ) {
|
||
|
||
global $post_type;
|
||
|
||
if ( 'shop_coupon' !== $post_type ) {
|
||
return false;
|
||
}
|
||
|
||
$coupon = new WC_Coupon( $coupon_id );
|
||
|
||
if ( is_a( $coupon, 'WC_Coupon' ) ) {
|
||
|
||
$scheduled_actions_ids = ( $this->is_callable( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'wc_sc_scheduled_actions_ids' ) : $this->get_post_meta( $coupon_id, 'wc_sc_scheduled_actions_ids', true );
|
||
|
||
if ( ! empty( $scheduled_actions_ids ) && is_array( $scheduled_actions_ids ) ) {
|
||
|
||
if ( ! class_exists( 'ActionScheduler' ) || ! is_callable( array( 'ActionScheduler', 'store' ) ) ) {
|
||
return false;
|
||
}
|
||
|
||
foreach ( $scheduled_actions_ids as $ref_key => $action_id ) {
|
||
$action_scheduler = ActionScheduler::store()->fetch_action( $action_id );
|
||
if ( is_a( $action_scheduler, 'ActionScheduler_Action' ) && is_callable( array( $action_scheduler, 'is_finished' ) ) ) {
|
||
$is_action_complete = $action_scheduler->is_finished();
|
||
|
||
// Delete only unfinished actions related to coupon.
|
||
if ( ! $is_action_complete ) {
|
||
ActionScheduler::store()->delete_action( $action_id );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Function to check if passed timestamp is valid.
|
||
*
|
||
* @param string $timestamp timestamp.
|
||
* @return boolean is valid timestamp.
|
||
*/
|
||
public function is_valid_timestamp( $timestamp = '' ) {
|
||
|
||
if ( empty( $timestamp ) || ! is_numeric( $timestamp ) ) {
|
||
return false;
|
||
}
|
||
|
||
// Check if time is already passed.
|
||
if ( time() > $timestamp ) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
/**
|
||
* Function to enqueue scripts in footer.
|
||
*/
|
||
public function enqueue_admin_footer_scripts() {
|
||
|
||
global $pagenow, $typenow;
|
||
|
||
if ( empty( $pagenow ) || 'edit.php' !== $pagenow ) {
|
||
return;
|
||
}
|
||
|
||
$coupon_status = ( ! empty( $_GET['post_status'] ) ) ? wc_clean( wp_unslash( $_GET['post_status'] ) ) : ''; // phpcs:ignore
|
||
if ( 'edit.php' === $pagenow && 'shop_coupon' === $typenow && 'trash' === $coupon_status ) {
|
||
if ( ! wp_script_is( 'jquery' ) ) {
|
||
wp_enqueue_script( 'jquery' );
|
||
}
|
||
?>
|
||
<script type="text/javascript">
|
||
jQuery(function(){
|
||
jQuery('body.post-type-shop_coupon .wp-list-table .delete a.submitdelete').click(function(e) {
|
||
e.preventDefault();
|
||
let coupon_delete_elem = jQuery(this);
|
||
let coupon_delete_url = jQuery(coupon_delete_elem).attr('href');
|
||
let coupon_id = jQuery(coupon_delete_elem).closest('.type-shop_coupon').find('[name="post[]"]').val();
|
||
jQuery.ajax({
|
||
url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
|
||
type: 'post',
|
||
dataType: 'json',
|
||
data: {
|
||
action: 'wc_sc_check_scheduled_coupon_actions',
|
||
security: '<?php echo esc_html( wp_create_nonce( 'wc-sc-check-coupon-scheduled-actions' ) ); ?>',
|
||
coupon_id: coupon_id
|
||
},
|
||
success: function( response ){
|
||
if ( undefined !== response.has_scheduled_actions && '' !== response.has_scheduled_actions && 'yes' === response.has_scheduled_actions ) {
|
||
let confirm_delete = window.confirm( '<?php echo esc_js( __( 'This coupon has pending emails to be sent. Deleting it will delete those emails also. Are you sure to delete this coupon?', 'woocommerce-smart-coupons' ) ); ?>' );
|
||
if( confirm_delete ) {
|
||
window.location.href = coupon_delete_url;
|
||
}
|
||
} else {
|
||
window.location.href = coupon_delete_url;
|
||
}
|
||
},
|
||
error: function( jq_xhr, exception ) {
|
||
alert( '<?php echo esc_js( __( 'An error has occurred. Please try again later.', 'woocommerce-smart-coupons' ) ); ?>' );
|
||
}
|
||
});
|
||
});
|
||
});
|
||
</script>
|
||
<?php
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Function to check if coupon has any pending scheduled actions.
|
||
*/
|
||
public function check_scheduled_coupon_actions() {
|
||
|
||
check_ajax_referer( 'wc-sc-check-coupon-scheduled-actions', 'security' );
|
||
|
||
$coupon_id = ( ! empty( $_POST['coupon_id'] ) ) ? wc_clean( wp_unslash( $_POST['coupon_id'] ) ) : ''; // phpcs:ignore
|
||
|
||
$response = array(
|
||
'has_scheduled_actions' => 'no',
|
||
);
|
||
|
||
if ( ! empty( $coupon_id ) ) {
|
||
$coupon = new WC_Coupon( $coupon_id );
|
||
if ( is_a( $coupon, 'WC_Coupon' ) ) {
|
||
$scheduled_actions_ids = ( $this->is_callable( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'wc_sc_scheduled_actions_ids' ) : $this->get_post_meta( $coupon_id, 'wc_sc_scheduled_actions_ids', true );
|
||
if ( is_array( $scheduled_actions_ids ) && ! empty( $scheduled_actions_ids ) ) {
|
||
$response['has_scheduled_actions'] = 'yes';
|
||
}
|
||
}
|
||
}
|
||
|
||
wp_send_json( $response );
|
||
}
|
||
|
||
/**
|
||
* Register new endpoint to use inside My Account page.
|
||
*/
|
||
public function sc_add_endpoints() {
|
||
|
||
if ( empty( WC_SC_Display_Coupons::$endpoint ) ) {
|
||
WC_SC_Display_Coupons::$endpoint = WC_SC_Display_Coupons::get_endpoint();
|
||
}
|
||
|
||
if ( $this->is_wc_gte_26() ) {
|
||
add_rewrite_endpoint( WC_SC_Display_Coupons::$endpoint, EP_ROOT | EP_PAGES );
|
||
$this->sc_check_if_flushed_rules();
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* To register Smart Coupons Endpoint after plugin is activated - Necessary
|
||
*/
|
||
public function sc_check_if_flushed_rules() {
|
||
$sc_check_flushed_rules = get_option( 'sc_flushed_rules', 'notfound' );
|
||
if ( 'notfound' === $sc_check_flushed_rules ) {
|
||
flush_rewrite_rules(); // phpcs:ignore
|
||
update_option( 'sc_flushed_rules', 'found', 'no' );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Register & enqueue Smart Coupons CSS
|
||
*/
|
||
public function register_plugin_styles() {
|
||
global $pagenow;
|
||
|
||
$is_frontend = ( ! is_admin() ) ? true : false;
|
||
$is_valid_post_page = ( ! empty( $pagenow ) && in_array( $pagenow, array( 'edit.php', 'post.php', 'post-new.php' ), true ) ) ? true : false;
|
||
$is_valid_admin_page = ( ( ! empty( $_GET['page'] ) && 'wc-smart-coupons' === wc_clean( wp_unslash( $_GET['page'] ) ) ) || ( ! empty( $_GET['tab'] ) && 'wc-smart-coupons' === wc_clean( wp_unslash( $_GET['tab'] ) ) ) ) ? true : false; // phpcs:ignore
|
||
|
||
if ( $is_frontend || $is_valid_admin_page || $is_valid_post_page ) {
|
||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||
wp_register_style( 'smart-coupon', untrailingslashit( plugins_url( '/', WC_SC_PLUGIN_FILE ) ) . '/assets/css/smart-coupon' . $suffix . '.css', array(), $this->plugin_data['Version'] );
|
||
wp_register_style( 'smart-coupon-designs', untrailingslashit( plugins_url( '/', WC_SC_PLUGIN_FILE ) ) . '/assets/css/smart-coupon-designs.css', array(), $this->plugin_data['Version'] );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get coupon style attributes
|
||
*
|
||
* @return string The coupon style attribute
|
||
*/
|
||
public function get_coupon_style_attributes() {
|
||
|
||
$styles = array();
|
||
|
||
$coupon_design = get_option( 'wc_sc_setting_coupon_design', 'basic' );
|
||
|
||
if ( 'custom-design' !== $coupon_design ) {
|
||
$styles = array(
|
||
'background-color: var(--sc-color1) !important;',
|
||
'color: var(--sc-color2) !important;',
|
||
'border-color: var(--sc-color3) !important;',
|
||
);
|
||
}
|
||
|
||
$styles = implode( ' ', $styles );
|
||
|
||
return apply_filters( 'wc_sc_coupon_style_attributes', $styles );
|
||
|
||
}
|
||
|
||
/**
|
||
* Get coupon container classes
|
||
*
|
||
* @return string The coupon container classes
|
||
*/
|
||
public function get_coupon_container_classes() {
|
||
|
||
return implode( ' ', apply_filters( 'wc_sc_coupon_container_classes', array( 'medium', get_option( 'wc_sc_setting_coupon_design', 'basic' ) ) ) );
|
||
|
||
}
|
||
|
||
/**
|
||
* Get coupon content classes
|
||
*
|
||
* @return string The coupon content classes
|
||
*/
|
||
public function get_coupon_content_classes() {
|
||
|
||
return implode( ' ', apply_filters( 'wc_sc_coupon_content_classes', array( 'dashed', 'small' ) ) );
|
||
|
||
}
|
||
|
||
/**
|
||
* Formatted coupon data
|
||
*
|
||
* @param WC_Coupon $coupon Coupon object.
|
||
* @return array $coupon_data Associative array containing formatted coupon data.
|
||
*/
|
||
public function get_coupon_meta_data( $coupon ) {
|
||
global $store_credit_label, $post;
|
||
|
||
$order = null;
|
||
|
||
if ( ! empty( $post->post_type ) && 'shop_order' === $post->post_type && ! empty( $post->ID ) ) {
|
||
$order = wc_get_order( $post->ID );
|
||
}
|
||
|
||
$all_discount_types = wc_get_coupon_types();
|
||
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$coupon_id = ( ! empty( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
|
||
$discount_type = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
|
||
} else {
|
||
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
|
||
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
|
||
}
|
||
|
||
$coupon_amount = $this->get_amount( $coupon, true, $order );
|
||
|
||
$coupon_data = array();
|
||
switch ( $discount_type ) {
|
||
case 'smart_coupon':
|
||
$coupon_data['coupon_type'] = ! empty( $store_credit_label['singular'] ) ? ucwords( $store_credit_label['singular'] ) : __( 'Store Credit', 'woocommerce-smart-coupons' );
|
||
$coupon_data['coupon_amount'] = wc_price( $coupon_amount );
|
||
break;
|
||
|
||
case 'fixed_cart':
|
||
$coupon_data['coupon_type'] = __( 'Cart Discount', 'woocommerce-smart-coupons' );
|
||
$coupon_data['coupon_amount'] = wc_price( $coupon_amount );
|
||
break;
|
||
|
||
case 'fixed_product':
|
||
$coupon_data['coupon_type'] = __( 'Product Discount', 'woocommerce-smart-coupons' );
|
||
$coupon_data['coupon_amount'] = wc_price( $coupon_amount );
|
||
break;
|
||
|
||
case 'percent_product':
|
||
$coupon_data['coupon_type'] = __( 'Product Discount', 'woocommerce-smart-coupons' );
|
||
$coupon_data['coupon_amount'] = $coupon_amount . '%';
|
||
break;
|
||
|
||
case 'percent':
|
||
$coupon_data['coupon_type'] = ( $this->is_wc_gte_30() ) ? __( 'Discount', 'woocommerce-smart-coupons' ) : __( 'Cart Discount', 'woocommerce-smart-coupons' );
|
||
$coupon_data['coupon_amount'] = $coupon_amount . '%';
|
||
$max_discount = $this->get_post_meta( $coupon_id, 'wc_sc_max_discount', true, true, $order );
|
||
if ( ! empty( $max_discount ) && is_numeric( $max_discount ) ) {
|
||
/* translators: %s: Maximum coupon discount amount */
|
||
$coupon_data['coupon_type'] .= ' ' . sprintf( __( ' upto %s', 'woocommerce-smart-coupons' ), wc_price( $max_discount ) );
|
||
}
|
||
break;
|
||
|
||
default:
|
||
$default_coupon_type = ( ! empty( $all_discount_types[ $discount_type ] ) ) ? $all_discount_types[ $discount_type ] : ucwords( str_replace( array( '_', '-' ), ' ', $discount_type ) );
|
||
$coupon_data['coupon_type'] = apply_filters( 'wc_sc_coupon_type', $default_coupon_type, $coupon, $all_discount_types );
|
||
$coupon_data['coupon_amount'] = apply_filters( 'wc_sc_coupon_amount', $coupon_amount, $coupon );
|
||
break;
|
||
|
||
}
|
||
return $coupon_data;
|
||
}
|
||
|
||
/**
|
||
* Generate coupon description
|
||
*
|
||
* @param array $args The arguments.
|
||
* @return string
|
||
*/
|
||
public function generate_coupon_description( $args = array() ) {
|
||
$coupon = ( ! empty( $args['coupon_object'] ) ) ? $args['coupon_object'] : null;
|
||
$descriptions = array();
|
||
$descriptions_data = array();
|
||
if ( $this->is_wc_gte_30() && is_object( $coupon ) ) {
|
||
$discount_type = ( is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
|
||
$expiry_time = ( is_callable( array( $coupon, 'get_meta' ) ) ) ? $coupon->get_meta( 'wc_sc_expiry_time' ) : '';
|
||
|
||
$expiry_needed_in_design = array( 'ticket', 'special' );
|
||
$design = get_option( 'wc_sc_setting_coupon_design', 'basic' );
|
||
|
||
$descriptions_data['minimum_amount'] = ( is_callable( array( $coupon, 'get_minimum_amount' ) ) ) ? $coupon->get_minimum_amount() : '';
|
||
$descriptions_data['maximum_amount'] = ( is_callable( array( $coupon, 'get_maximum_amount' ) ) ) ? $coupon->get_maximum_amount() : '';
|
||
$descriptions_data['exclude_sale_items'] = ( is_callable( array( $coupon, 'get_exclude_sale_items' ) ) ) ? $coupon->get_exclude_sale_items() : '';
|
||
$descriptions_data['product_ids'] = ( is_callable( array( $coupon, 'get_product_ids' ) ) ) ? $coupon->get_product_ids() : array();
|
||
$descriptions_data['excluded_product_ids'] = ( is_callable( array( $coupon, 'get_excluded_product_ids' ) ) ) ? $coupon->get_excluded_product_ids() : array();
|
||
$descriptions_data['product_categories'] = ( is_callable( array( $coupon, 'get_product_categories' ) ) ) ? $coupon->get_product_categories() : array();
|
||
$descriptions_data['excluded_product_categories'] = ( is_callable( array( $coupon, 'get_excluded_product_categories' ) ) ) ? $coupon->get_excluded_product_categories() : array();
|
||
|
||
$check_descriptions_data = array_filter( $descriptions_data );
|
||
|
||
if ( in_array( $design, $expiry_needed_in_design, true ) || empty( $check_descriptions_data ) ) {
|
||
$descriptions_data['date_expires'] = ( is_callable( array( $coupon, 'get_date_expires' ) ) ) ? $coupon->get_date_expires() : '';
|
||
}
|
||
|
||
$max_fields = apply_filters(
|
||
'wc_sc_max_fields_to_show_in_coupon_description',
|
||
2,
|
||
array(
|
||
'source' => $this,
|
||
'coupon_object' => $coupon,
|
||
)
|
||
);
|
||
|
||
if ( ! empty( $descriptions_data ) ) {
|
||
foreach ( $descriptions_data as $key => $data ) {
|
||
if ( count( $descriptions ) > $max_fields ) {
|
||
break;
|
||
}
|
||
if ( ! empty( $data ) ) {
|
||
switch ( $key ) {
|
||
case 'minimum_amount':
|
||
/* translators: Formatted minimum amount */
|
||
$descriptions[] = sprintf( __( 'Spend at least %s', 'woocommerce-smart-coupons' ), wc_price( $data ) );
|
||
break;
|
||
case 'maximum_amount':
|
||
/* translators: Formatted maximum amount */
|
||
$descriptions[] = sprintf( __( 'Spend up to %s', 'woocommerce-smart-coupons' ), wc_price( $data ) );
|
||
break;
|
||
case 'exclude_sale_items':
|
||
/* translators: Formatted maximum amount */
|
||
$descriptions[] = sprintf( __( 'Not valid for sale items', 'woocommerce-smart-coupons' ), wc_price( $data ) );
|
||
break;
|
||
case 'product_ids':
|
||
$get_product_names = $this->get_coupon_product_names( $data );
|
||
$product_names = ( ! empty( $get_product_names ) && is_array( $get_product_names ) ) ? implode( ', ', $get_product_names ) : '';
|
||
/* translators: Product names */
|
||
$descriptions[] = sprintf( __( 'Valid for %s', 'woocommerce-smart-coupons' ), $product_names );
|
||
break;
|
||
case 'excluded_product_ids':
|
||
$get_product_names = $this->get_coupon_product_names( $data );
|
||
$product_names = ( ! empty( $get_product_names ) && is_array( $get_product_names ) ) ? implode( ', ', $get_product_names ) : '';
|
||
/* translators: Excluded product names */
|
||
$descriptions[] = sprintf( __( 'Not valid for %s', 'woocommerce-smart-coupons' ), $product_names );
|
||
break;
|
||
case 'product_categories':
|
||
$get_product_categories = $this->get_coupon_category_names( $data );
|
||
$product_categories = ( ! empty( $get_product_categories ) ) ? implode( ', ', $get_product_categories ) : '';
|
||
$count_product_categories = ( ! empty( $get_product_categories ) ) ? count( $get_product_categories ) : 1;
|
||
/* translators: 1: The category names */
|
||
$descriptions[] = sprintf( esc_html( _n( 'Valid for category %s', 'Valid for categories %s', $count_product_categories, 'woocommerce-smart-coupons' ) ), $product_categories );
|
||
break;
|
||
case 'excluded_product_categories':
|
||
$get_product_categories = $this->get_coupon_category_names( $data );
|
||
$product_categories = ( ! empty( $get_product_categories ) ) ? implode( ', ', $get_product_categories ) : '';
|
||
$count_product_categories = ( ! empty( $get_product_categories ) ) ? count( $get_product_categories ) : 1;
|
||
/* translators: 1: The category names excluded */
|
||
$descriptions[] = sprintf( esc_html( _n( 'Not valid for category %s', 'Not valid for categories %s', $count_product_categories, 'woocommerce-smart-coupons' ) ), $product_categories );
|
||
break;
|
||
case 'date_expires':
|
||
if ( $data instanceof WC_DateTime ) {
|
||
$expiry_date = ( is_object( $data ) && is_callable( array( $data, 'getTimestamp' ) ) ) ? $data->getTimestamp() : null;
|
||
} elseif ( ! is_int( $expiry_date ) ) {
|
||
$expiry_date = strtotime( $expiry_date );
|
||
}
|
||
if ( ! empty( $expiry_date ) && is_int( $expiry_date ) && ! empty( $expiry_time ) ) {
|
||
$expiry_date += $expiry_time; // Adding expiry time to expiry date.
|
||
}
|
||
if ( ! empty( $expiry_date ) ) {
|
||
/* translators: 1: The expiry date */
|
||
$descriptions[] = sprintf( __( 'Expiry: %s', 'woocommerce-smart-coupons' ), $this->get_expiration_format( $expiry_date ) );
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if ( empty( $descriptions ) ) {
|
||
$descriptions[] = __( 'Valid on entire range of products. Buy anything in the store.', 'woocommerce-smart-coupons' );
|
||
}
|
||
return apply_filters(
|
||
'wc_sc_generated_coupon_description',
|
||
implode( '. ', $descriptions ),
|
||
array(
|
||
'source' => $this,
|
||
'coupon_object' => $coupon,
|
||
)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Get coupon category names.
|
||
*
|
||
* @since 5.7.0
|
||
*
|
||
* @param array $category_ids Category IDs.
|
||
* @return array
|
||
*/
|
||
public function get_coupon_category_names( $category_ids = array() ) {
|
||
$category_names = array();
|
||
|
||
if ( empty( $category_ids ) || ! is_array( $category_ids ) ) {
|
||
return $category_names;
|
||
}
|
||
|
||
$category_name_count_restriction = (int) apply_filters(
|
||
'wc_sc_max_restricted_category_names',
|
||
2,
|
||
array(
|
||
'source' => $this,
|
||
'data' => $category_ids,
|
||
)
|
||
);
|
||
|
||
if ( count( $category_ids ) > $category_name_count_restriction ) {
|
||
$category_ids = array_slice( $category_ids, 0, $category_name_count_restriction );
|
||
}
|
||
$category_names = get_terms(
|
||
array(
|
||
'taxonomy' => 'product_cat',
|
||
'include' => $category_ids,
|
||
'fields' => 'id=>name',
|
||
'get' => 'all',
|
||
)
|
||
);
|
||
|
||
return array_filter( $category_names );
|
||
}
|
||
|
||
/**
|
||
* Get coupon product's names.
|
||
*
|
||
* @since 5.7.0
|
||
*
|
||
* @param array $product_ids Product IDs.
|
||
* @return array
|
||
*/
|
||
public function get_coupon_product_names( $product_ids = array() ) {
|
||
$product_names = array();
|
||
|
||
if ( empty( $product_ids ) || ! is_array( $product_ids ) ) {
|
||
return $product_names;
|
||
}
|
||
|
||
$data_count = count( $product_ids );
|
||
$product_name_count = 0;
|
||
|
||
$product_name_count_restriction = (int) apply_filters(
|
||
'wc_sc_max_restricted_product_names',
|
||
2,
|
||
array(
|
||
'source' => $this,
|
||
'data' => $product_ids,
|
||
)
|
||
);
|
||
|
||
for ( $i = 0; $i < $data_count && $product_name_count < $product_name_count_restriction; $i++ ) {
|
||
$product = wc_get_product( $product_ids[ $i ] );
|
||
if ( is_object( $product ) && is_callable( array( $product, 'get_name' ) ) ) {
|
||
$product_names[] = $product->get_name();
|
||
$product_name_count++;
|
||
}
|
||
}
|
||
|
||
return array_filter( $product_names );
|
||
|
||
}
|
||
|
||
/**
|
||
* Get valid coupon designs
|
||
*
|
||
* @return array
|
||
*/
|
||
public function get_valid_coupon_designs() {
|
||
$valid_designs = array(
|
||
'flat',
|
||
'promotion',
|
||
'ticket',
|
||
'festive',
|
||
'special',
|
||
'shipment',
|
||
'cutout',
|
||
'deliver',
|
||
'clipper',
|
||
'basic',
|
||
'deal',
|
||
'custom-design',
|
||
);
|
||
return $valid_designs;
|
||
}
|
||
|
||
/**
|
||
* Get coupon design thumbnail src
|
||
*
|
||
* @param array $args The arguments.
|
||
* @return string
|
||
*/
|
||
public function get_coupon_design_thumbnail_src( $args = array() ) {
|
||
$coupon = ( ! empty( $args['coupon_object'] ) ) ? $args['coupon_object'] : null;
|
||
$src = '';
|
||
$src_selected = '';
|
||
$placeholder = wc_placeholder_img_src();
|
||
if ( is_object( $coupon ) ) {
|
||
$coupon_product_ids = ( is_callable( array( $coupon, 'get_product_ids' ) ) ) ? $coupon->get_product_ids() : array();
|
||
if ( ! empty( $coupon_product_ids ) ) {
|
||
$product_id = current( $coupon_product_ids );
|
||
$product = wc_get_product( $product_id );
|
||
$thumbnail_id = ( is_object( $product ) && is_callable( array( $product, 'get_image_id' ) ) ) ? $product->get_image_id() : '';
|
||
} else {
|
||
$coupon_product_category_ids = ( is_callable( array( $coupon, 'get_product_categories' ) ) ) ? $coupon->get_product_categories() : array();
|
||
if ( ! empty( $coupon_product_category_ids ) ) {
|
||
$category_id = current( $coupon_product_category_ids );
|
||
$thumbnail_id = get_term_meta( $category_id, 'thumbnail_id', true );
|
||
}
|
||
}
|
||
$src_array = ( ! empty( $thumbnail_id ) ) ? wp_get_attachment_image_src( $thumbnail_id, 'woocommerce_thumbnail' ) : array();
|
||
$src = ( ! empty( $src_array[0] ) ) ? $src_array[0] : wc_placeholder_img_src();
|
||
if ( ! empty( $src ) && strpos( $src, $placeholder ) !== false ) {
|
||
$src = '';
|
||
}
|
||
}
|
||
if ( empty( $src ) ) {
|
||
$src_set = array();
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$discount_type = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
|
||
$is_free_shipping = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_free_shipping' ) ) ) ? ( ( $coupon->get_free_shipping() ) ? 'yes' : 'no' ) : '';
|
||
} else {
|
||
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
|
||
$is_free_shipping = ( ! empty( $coupon->free_shipping ) ) ? $coupon->free_shipping : '';
|
||
}
|
||
|
||
if ( 'yes' === $is_free_shipping ) {
|
||
$src_set = array(
|
||
'delivery-motorcyle.svg',
|
||
);
|
||
} else {
|
||
switch ( $discount_type ) {
|
||
case 'smart_coupon':
|
||
$src_set = array(
|
||
'giftbox-color.svg',
|
||
);
|
||
break;
|
||
|
||
case 'fixed_cart':
|
||
$src_set = array(
|
||
'sale-splash-tag.svg',
|
||
);
|
||
break;
|
||
|
||
case 'fixed_product':
|
||
$src_set = array(
|
||
'product-package-box.svg',
|
||
);
|
||
break;
|
||
|
||
case 'percent_product':
|
||
$src_set = array(
|
||
'cart-discount.svg',
|
||
);
|
||
break;
|
||
|
||
case 'percent':
|
||
$src_set = array(
|
||
'cart-discount.svg',
|
||
);
|
||
break;
|
||
|
||
default:
|
||
$src_set = apply_filters(
|
||
'wc_sc_coupon_design_thumbnail_src_set',
|
||
array( 'discount-coupon.svg' ),
|
||
array(
|
||
'source' => $this,
|
||
'coupon_object' => $coupon,
|
||
)
|
||
);
|
||
break;
|
||
|
||
}
|
||
}
|
||
if ( ! empty( $src_set ) ) {
|
||
$src_index = array_rand( $src_set );
|
||
$src_selected = $src_set[ $src_index ];
|
||
$file = trailingslashit( plugins_url( '/', WC_SC_PLUGIN_FILE ) ) . 'assets/images/' . $src_selected;
|
||
$src = apply_filters(
|
||
'wc_sc_coupon_design_thumbnail_src',
|
||
$file,
|
||
array(
|
||
'source' => $this,
|
||
'selected' => $src_selected,
|
||
'coupon_object' => $coupon,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
if ( empty( $src ) ) {
|
||
$design = ( ! empty( $args['design'] ) ) ? $args['design'] : '';
|
||
if ( ! empty( $design ) ) {
|
||
switch ( $design ) {
|
||
case 'special':
|
||
$src_selected = 'giftbox-color.svg';
|
||
break;
|
||
case 'shipment':
|
||
$src_selected = 'product-package-box.svg';
|
||
break;
|
||
case 'cutout':
|
||
$src_selected = 'cart-discount.svg';
|
||
break;
|
||
case 'deliver':
|
||
$src_selected = 'delivery-motorcyle.svg';
|
||
break;
|
||
case 'deal':
|
||
$src_selected = 'discount-coupon.svg';
|
||
break;
|
||
case 'flat':
|
||
case 'promotion':
|
||
case 'ticket':
|
||
case 'festive':
|
||
case 'clipper':
|
||
case 'basic':
|
||
default:
|
||
$src_selected = 'discount-coupon.svg';
|
||
break;
|
||
}
|
||
if ( ! empty( $src_selected ) ) {
|
||
$file = trailingslashit( plugins_url( '/', WC_SC_PLUGIN_FILE ) ) . 'assets/images/' . $src_selected;
|
||
$src = apply_filters(
|
||
'wc_sc_coupon_design_thumbnail_src',
|
||
$file,
|
||
array(
|
||
'source' => $this,
|
||
'selected' => $src_selected,
|
||
'coupon_object' => $coupon,
|
||
)
|
||
);
|
||
} else {
|
||
$src = '';
|
||
}
|
||
}
|
||
}
|
||
return $src;
|
||
}
|
||
|
||
/**
|
||
* Find if the discount type is percent
|
||
*
|
||
* @param array $args The arguments.
|
||
* @return boolean
|
||
*/
|
||
public function is_percent_coupon( $args = array() ) {
|
||
$is_percent = false;
|
||
$coupon = ( ! empty( $args['coupon_object'] ) ) ? $args['coupon_object'] : null;
|
||
$percent_discount_types = apply_filters(
|
||
'wc_sc_percent_discount_types',
|
||
array( 'percent_product', 'percent' ),
|
||
array(
|
||
'source' => $this,
|
||
'coupon_object' => $coupon,
|
||
)
|
||
);
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$discount_type = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
|
||
} else {
|
||
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
|
||
}
|
||
if ( in_array( $discount_type, $percent_discount_types, true ) ) {
|
||
$is_percent = true;
|
||
}
|
||
return $is_percent;
|
||
}
|
||
|
||
/**
|
||
* Generate storewide offer coupon description
|
||
*
|
||
* @param array $args Arguments.
|
||
* @return string
|
||
*/
|
||
public function generate_storewide_offer_coupon_description( $args = array() ) {
|
||
$coupon = ( ! empty( $args['coupon_object'] ) ) ? $args['coupon_object'] : false;
|
||
$coupon_amount = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_amount' ) ) ) ? $coupon->get_amount( 'edit' ) : 0;
|
||
$coupon_code = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
|
||
|
||
if ( empty( $coupon_amount ) || empty( $coupon_code ) ) {
|
||
return '';
|
||
}
|
||
|
||
$description = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_description' ) ) ) ? $coupon->get_description() : '';
|
||
|
||
if ( empty( $description ) ) {
|
||
|
||
$is_percent = $this->is_percent_coupon( array( 'coupon_object' => $coupon ) );
|
||
$currency_symbol = get_woocommerce_currency_symbol();
|
||
|
||
$before_heading = array(
|
||
__( 'Great News!', 'woocommerce-smart-coupons' ),
|
||
__( 'Super Savings!', 'woocommerce-smart-coupons' ),
|
||
__( 'Ending Soon!', 'woocommerce-smart-coupons' ),
|
||
__( 'Limited Time Offer!', 'woocommerce-smart-coupons' ),
|
||
__( 'This Week Only!', 'woocommerce-smart-coupons' ),
|
||
__( 'Attention!', 'woocommerce-smart-coupons' ),
|
||
__( 'You don\'t want to miss this...', 'woocommerce-smart-coupons' ),
|
||
__( 'This will be over soon! Hurry.', 'woocommerce-smart-coupons' ),
|
||
__( 'Act before the offer expires.', 'woocommerce-smart-coupons' ),
|
||
__( 'Don't Miss Out.', 'woocommerce-smart-coupons' ),
|
||
);
|
||
|
||
$heading = array(
|
||
/* translators: 1. The discount text */
|
||
__( '%s discount on anything you want.', 'woocommerce-smart-coupons' ),
|
||
/* translators: 1. The discount text */
|
||
__( '%s discount on entire store.', 'woocommerce-smart-coupons' ),
|
||
/* translators: 1. The discount text */
|
||
__( 'Pick any item today for %s off.', 'woocommerce-smart-coupons' ),
|
||
/* translators: 1. The discount text */
|
||
__( 'Buy as much as you want. Flat %s off everything.', 'woocommerce-smart-coupons' ),
|
||
/* translators: 1. The discount text */
|
||
__( 'Flat %s discount on everything today.', 'woocommerce-smart-coupons' ),
|
||
);
|
||
|
||
$before_heading_index = array_rand( $before_heading );
|
||
$heading_index = array_rand( $heading );
|
||
|
||
if ( true === $is_percent ) {
|
||
$discount_text = $coupon_amount . '%';
|
||
} else {
|
||
$discount_text = $currency_symbol . $coupon_amount;
|
||
}
|
||
|
||
$description = sprintf( '%s ' . $heading[ $heading_index ] . ' %s: %s', $before_heading[ $before_heading_index ], '<strong style="font-size: 1.1rem;">' . $discount_text . '</strong>', __( 'Use code', 'woocommerce-smart-coupons' ), '<code>' . $coupon_code . '</code>' );
|
||
|
||
$description = apply_filters(
|
||
'wc_sc_storewide_offer_coupon_description',
|
||
$description,
|
||
array_merge(
|
||
$args,
|
||
array(
|
||
'before_heading' => $before_heading[ $before_heading_index ],
|
||
'heading' => $heading,
|
||
'discount_text' => $discount_text,
|
||
)
|
||
)
|
||
);
|
||
|
||
} else {
|
||
/* translators: 1. The coupon code */
|
||
$description .= ' ' . sprintf( __( 'Use code: %s', 'woocommerce-smart-coupons' ), '<code>' . $coupon_code . '</code>' );
|
||
}
|
||
|
||
return $description;
|
||
|
||
}
|
||
|
||
/**
|
||
* Update coupon's email id with the updation of customer profile
|
||
*
|
||
* @param int $user_id User ID of the user being saved.
|
||
*/
|
||
public function my_profile_update( $user_id ) {
|
||
|
||
global $wpdb;
|
||
|
||
if ( current_user_can( 'edit_user', $user_id ) ) {
|
||
|
||
$current_user = get_userdata( $user_id );
|
||
|
||
$old_customers_email_id = $current_user->data->user_email;
|
||
|
||
$post_email = ( isset( $_POST['email'] ) ) ? wc_clean( wp_unslash( $_POST['email'] ) ) : ''; // phpcs:ignore
|
||
|
||
if ( ! empty( $post_email ) && $post_email !== $old_customers_email_id ) {
|
||
|
||
$result = wp_cache_get( 'wc_sc_customers_coupon_ids_' . sanitize_key( $old_customers_email_id ), 'woocommerce_smart_coupons' );
|
||
|
||
if ( false === $result ) {
|
||
$result = $wpdb->get_col( // phpcs:ignore
|
||
$wpdb->prepare(
|
||
"SELECT post_id
|
||
FROM $wpdb->postmeta
|
||
WHERE meta_key = %s
|
||
AND meta_value LIKE %s
|
||
AND post_id IN ( SELECT ID
|
||
FROM $wpdb->posts
|
||
WHERE post_type = %s)",
|
||
'customer_email',
|
||
'%' . $wpdb->esc_like( $old_customers_email_id ) . '%',
|
||
'shop_coupon'
|
||
)
|
||
);
|
||
wp_cache_set( 'wc_sc_customers_coupon_ids_' . sanitize_key( $old_customers_email_id ), $result, 'woocommerce_smart_coupons' );
|
||
$this->maybe_add_cache_key( 'wc_sc_customers_coupon_ids_' . sanitize_key( $old_customers_email_id ) );
|
||
}
|
||
|
||
if ( ! empty( $result ) ) {
|
||
|
||
foreach ( $result as $post_id ) {
|
||
|
||
$coupon_meta = $this->get_post_meta( $post_id, 'customer_email', true );
|
||
$is_update_coupon_meta = false;
|
||
|
||
if ( ! empty( $coupon_meta ) ) {
|
||
foreach ( $coupon_meta as $key => $email_id ) {
|
||
if ( $email_id === $old_customers_email_id ) {
|
||
$coupon_meta[ $key ] = $post_email;
|
||
$is_update_coupon_meta = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( true === $is_update_coupon_meta ) {
|
||
$this->update_post_meta( $post_id, 'customer_email', $coupon_meta );
|
||
}
|
||
} //end foreach
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Method to check whether 'pick_price_from_product' is set or not
|
||
*
|
||
* @param array $coupons Array of coupon codes.
|
||
* @return boolean
|
||
*/
|
||
public function is_coupon_amount_pick_from_product_price( $coupons ) {
|
||
|
||
if ( empty( $coupons ) ) {
|
||
return false;
|
||
}
|
||
|
||
foreach ( $coupons as $coupon_code ) {
|
||
$coupon = new WC_Coupon( $coupon_code );
|
||
if ( $this->is_wc_gte_30() ) {
|
||
if ( ! is_object( $coupon ) || ! is_callable( array( $coupon, 'get_id' ) ) ) {
|
||
continue;
|
||
}
|
||
$coupon_id = $coupon->get_id();
|
||
if ( empty( $coupon_id ) ) {
|
||
continue;
|
||
}
|
||
$discount_type = $coupon->get_discount_type();
|
||
$is_pick_price_of_product = ( $this->is_callable( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'is_pick_price_of_product' ) : $this->get_post_meta( $coupon_id, 'is_pick_price_of_product', true );
|
||
} else {
|
||
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
|
||
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
|
||
$is_pick_price_of_product = get_post_meta( $coupon_id, 'is_pick_price_of_product', true );
|
||
}
|
||
if ( 'smart_coupon' === $discount_type && 'yes' === $is_pick_price_of_product ) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Function to find if order is discounted with store credit
|
||
*
|
||
* @param WC_Order $order Order object.
|
||
* @return boolean
|
||
*/
|
||
public function is_order_contains_store_credit( $order = null ) {
|
||
|
||
if ( empty( $order ) ) {
|
||
return false;
|
||
}
|
||
|
||
$coupons = $order->get_items( 'coupon' );
|
||
|
||
foreach ( $coupons as $item_id => $item ) {
|
||
$code = ( is_object( $item ) && is_callable( array( $item, 'get_name' ) ) ) ? $item->get_name() : trim( $item['name'] );
|
||
$coupon = new WC_Coupon( $code );
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$discount_type = $coupon->get_discount_type();
|
||
} else {
|
||
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
|
||
}
|
||
if ( 'smart_coupon' === $discount_type ) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
|
||
}
|
||
|
||
/**
|
||
* Function to validate smart coupon for product
|
||
*
|
||
* @param bool $valid Coupon validity.
|
||
* @param WC_Product|null $product Product object.
|
||
* @param WC_Coupon|null $coupon Coupon object.
|
||
* @param array|null $values Values.
|
||
* @return bool $valid
|
||
*/
|
||
public function smart_coupons_is_valid_for_product( $valid, $product = null, $coupon = null, $values = null ) {
|
||
|
||
if ( empty( $product ) || empty( $coupon ) ) {
|
||
return $valid;
|
||
}
|
||
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$product_id = ( is_object( $product ) && is_callable( array( $product, 'get_id' ) ) ) ? $product->get_id() : 0;
|
||
$product_parent_id = ( is_object( $product ) && is_callable( array( $product, 'get_parent_id' ) ) ) ? $product->get_parent_id() : 0;
|
||
$product_variation_id = ( is_object( $product ) && is_callable( array( $product, 'get_id' ) ) ) ? $product->get_id() : 0;
|
||
$discount_type = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
|
||
$coupon_product_ids = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_product_ids' ) ) ) ? $coupon->get_product_ids() : '';
|
||
$coupon_product_categories = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_product_categories' ) ) ) ? $coupon->get_product_categories() : '';
|
||
$coupon_excluded_product_ids = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_excluded_product_ids' ) ) ) ? $coupon->get_excluded_product_ids() : '';
|
||
$coupon_excluded_product_categories = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_excluded_product_categories' ) ) ) ? $coupon->get_excluded_product_categories() : '';
|
||
$is_exclude_sale_items = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_exclude_sale_items' ) ) ) ? ( ( $coupon->get_exclude_sale_items() ) ? 'yes' : 'no' ) : '';
|
||
} else {
|
||
$product_id = ( ! empty( $product->id ) ) ? $product->id : 0;
|
||
$product_parent_id = ( ! empty( $product ) && is_callable( array( $product, 'get_parent' ) ) ) ? $product->get_parent() : 0;
|
||
$product_variation_id = ( ! empty( $product->variation_id ) ) ? $product->variation_id : 0;
|
||
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
|
||
$coupon_product_ids = ( ! empty( $coupon->product_ids ) ) ? $coupon->product_ids : array();
|
||
$coupon_product_categories = ( ! empty( $coupon->product_categories ) ) ? $coupon->product_categories : array();
|
||
$coupon_excluded_product_ids = ( ! empty( $coupon->exclude_product_ids ) ) ? $coupon->exclude_product_ids : array();
|
||
$coupon_excluded_product_categories = ( ! empty( $coupon->exclude_product_categories ) ) ? $coupon->exclude_product_categories : array();
|
||
$is_exclude_sale_items = ( ! empty( $coupon->exclude_sale_items ) ) ? $coupon->exclude_sale_items : '';
|
||
}
|
||
|
||
if ( 'smart_coupon' === $discount_type ) {
|
||
|
||
$product_cats = wc_get_product_cat_ids( $product_id );
|
||
|
||
// Specific products get the discount.
|
||
if ( count( $coupon_product_ids ) > 0 ) {
|
||
|
||
if ( in_array( $product_id, $coupon_product_ids, true ) || ( isset( $product_variation_id ) && in_array( $product_variation_id, $coupon_product_ids, true ) ) || in_array( $product_parent_id, $coupon_product_ids, true ) ) {
|
||
$valid = true;
|
||
}
|
||
|
||
// Category discounts.
|
||
} elseif ( count( $coupon_product_categories ) > 0 ) {
|
||
|
||
if ( count( array_intersect( $product_cats, $coupon_product_categories ) ) > 0 ) {
|
||
$valid = true;
|
||
}
|
||
} else {
|
||
// No product ids - all items discounted.
|
||
$valid = true;
|
||
}
|
||
|
||
// Specific product ID's excluded from the discount.
|
||
if ( count( $coupon_excluded_product_ids ) > 0 ) {
|
||
if ( in_array( $product_id, $coupon_excluded_product_ids, true ) || ( isset( $product_variation_id ) && in_array( $product_variation_id, $coupon_excluded_product_ids, true ) ) || in_array( $product_parent_id, $coupon_excluded_product_ids, true ) ) {
|
||
$valid = false;
|
||
}
|
||
}
|
||
|
||
// Specific categories excluded from the discount.
|
||
if ( count( $coupon_excluded_product_categories ) > 0 ) {
|
||
if ( count( array_intersect( $product_cats, $coupon_excluded_product_categories ) ) > 0 ) {
|
||
$valid = false;
|
||
}
|
||
}
|
||
|
||
// Sale Items excluded from discount.
|
||
if ( 'yes' === $is_exclude_sale_items ) {
|
||
$product_ids_on_sale = wc_get_product_ids_on_sale();
|
||
|
||
if ( in_array( $product_id, $product_ids_on_sale, true ) || ( isset( $product_variation_id ) && in_array( $product_variation_id, $product_ids_on_sale, true ) ) || in_array( $product_parent_id, $product_ids_on_sale, true ) ) {
|
||
$valid = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
return $valid;
|
||
}
|
||
|
||
/**
|
||
* Validate expiry time
|
||
*
|
||
* @param boolean $expired Whether the coupon is expired or not.
|
||
* @param WC_Coupon $coupon The coupon object.
|
||
* @param WC_Discounts $discounts The discount object.
|
||
* @return boolean
|
||
*/
|
||
public function validate_expiry_time( $expired = false, $coupon = null, $discounts = null ) {
|
||
|
||
if ( ! $this->is_wc_gte_30() ) {
|
||
return $expired; // Expiry time feature is not supported for lower version of WooCommerce.
|
||
}
|
||
|
||
$expiry_time = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_meta' ) ) ) ? $coupon->get_meta( 'wc_sc_expiry_time' ) : 0;
|
||
|
||
if ( ! empty( $expiry_time ) ) {
|
||
$expiry_date = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_date_expires' ) ) ) ? $coupon->get_date_expires() : '';
|
||
if ( ! empty( $expiry_date ) ) {
|
||
if ( $expiry_date instanceof WC_DateTime ) {
|
||
$expiry_date = ( is_callable( array( $expiry_date, 'getTimestamp' ) ) ) ? $expiry_date->getTimestamp() : null;
|
||
} elseif ( ! is_int( $expiry_date ) ) {
|
||
$expiry_date = strtotime( $expiry_date );
|
||
}
|
||
if ( is_int( $expiry_date ) ) {
|
||
$expiry_date += $expiry_time; // Adding expiry time to expiry date.
|
||
if ( time() <= $expiry_date ) {
|
||
$expired = false;
|
||
} else {
|
||
$expired = true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return $expired;
|
||
}
|
||
|
||
/**
|
||
* Function to keep valid coupons when individual use coupon is applied
|
||
*
|
||
* @param array $coupons_to_keep Coupons to keep.
|
||
* @param WC_Coupon|boolean $the_coupon Coupon object.
|
||
* @param array $applied_coupons Array of applied coupons.
|
||
* @return array $coupons_to_keep
|
||
*/
|
||
public function smart_coupons_override_individual_use( $coupons_to_keep = array(), $the_coupon = false, $applied_coupons = array() ) {
|
||
|
||
if ( $this->is_wc_gte_30() ) {
|
||
foreach ( $applied_coupons as $code ) {
|
||
$coupon = new WC_Coupon( $code );
|
||
if ( 'smart_coupon' === $coupon->get_discount_type() && ! $coupon->get_individual_use() && ! in_array( $code, $coupons_to_keep, true ) ) {
|
||
$coupons_to_keep[] = $code;
|
||
}
|
||
}
|
||
}
|
||
|
||
return $coupons_to_keep;
|
||
}
|
||
|
||
/**
|
||
* Force apply store credit even if the individual coupon already exists in cart
|
||
*
|
||
* @param boolean $is_apply Apply with individual use coupon.
|
||
* @param WC_Coupon|boolean $the_coupon Coupon object.
|
||
* @param WC_Coupon|boolean $applied_coupon Coupon object.
|
||
* @param array $applied_coupons Array of applied coupons.
|
||
* @return boolean
|
||
*/
|
||
public function smart_coupons_override_with_individual_use( $is_apply = false, $the_coupon = false, $applied_coupon = false, $applied_coupons = array() ) {
|
||
|
||
if ( $this->is_wc_gte_30() ) {
|
||
if ( ! $is_apply && 'smart_coupon' === $the_coupon->get_discount_type() && ! $the_coupon->get_individual_use() ) {
|
||
$is_apply = true;
|
||
}
|
||
}
|
||
|
||
return $is_apply;
|
||
}
|
||
|
||
/**
|
||
* Function to add appropriate discount total filter
|
||
*/
|
||
public function smart_coupons_discount_total_filters() {
|
||
if ( WCS_SC_Compatibility::is_cart_contains_subscription() && WCS_SC_Compatibility::is_wcs_gte( '2.0.0' ) ) {
|
||
add_action( 'woocommerce_after_calculate_totals', array( $this, 'smart_coupons_after_calculate_totals' ), 9999 );
|
||
} else {
|
||
add_action( 'woocommerce_after_calculate_totals', array( $this, 'smart_coupons_after_calculate_totals' ), 9999 );
|
||
global $current_screen;
|
||
if ( ! empty( $current_screen ) && 'edit-shop_order' !== $current_screen ) {
|
||
add_filter( 'woocommerce_order_get_total', array( $this, 'smart_coupons_order_discounted_total' ), 10, 2 );
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Function to handle store credit application
|
||
*/
|
||
public function sc_handle_store_credit_application() {
|
||
$apply_before_tax = get_option( 'woocommerce_smart_coupon_apply_before_tax', 'no' );
|
||
|
||
if ( $this->is_wc_gte_30() && 'yes' === $apply_before_tax ) {
|
||
include_once 'class-wc-sc-apply-before-tax.php';
|
||
} else {
|
||
add_action( 'wp_loaded', array( $this, 'smart_coupons_discount_total_filters' ), 20 );
|
||
add_action( 'woocommerce_order_after_calculate_totals', array( $this, 'order_calculate_discount_amount' ), 10, 2 );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Function to set store credit amount for orders that are manually created and updated from backend
|
||
*
|
||
* @param bool $and_taxes Calc taxes if true.
|
||
* @param WC_Order $order Order object.
|
||
*/
|
||
public function order_calculate_discount_amount( $and_taxes, $order ) {
|
||
if ( ! is_object( $order ) || ! $order instanceof WC_Order ) {
|
||
return;
|
||
}
|
||
$order_actions = array( 'woocommerce_add_coupon_discount', 'woocommerce_calc_line_taxes', 'woocommerce_save_order_items' );
|
||
|
||
$post_action = ( ! empty( $_POST['action'] ) ) ? wc_clean( wp_unslash( $_POST['action'] ) ) : ''; // phpcs:ignore
|
||
$post_post_type = ( ! empty( $_POST['post_type'] ) ) ? wc_clean( wp_unslash( $_POST['post_type'] ) ) : ''; // phpcs:ignore
|
||
|
||
$order_created_via = ( is_callable( array( $order, 'get_created_via' ) ) ) ? $order->get_created_via() : '';
|
||
|
||
if ( ( ! empty( $post_action ) && ( in_array( $post_action, $order_actions, true ) || ( ! empty( $post_post_type ) && 'shop_order' === $post_post_type && 'editpost' === $post_action ) ) ) || 'rest-api' === $order_created_via ) {
|
||
if ( ! is_callable( array( $order, 'get_id' ) ) ) {
|
||
return;
|
||
}
|
||
$order_id = $order->get_id();
|
||
if ( empty( $order_id ) ) {
|
||
return;
|
||
}
|
||
$coupons = $order->get_items( 'coupon' );
|
||
|
||
if ( ! empty( $coupons ) ) {
|
||
foreach ( $coupons as $item_id => $item ) {
|
||
$coupon_code = ( is_object( $item ) && is_callable( array( $item, 'get_name' ) ) ) ? $item->get_name() : trim( $item['name'] );
|
||
|
||
if ( empty( $coupon_code ) ) {
|
||
continue;
|
||
}
|
||
|
||
$coupon = new WC_Coupon( $coupon_code );
|
||
$discount_type = $coupon->get_discount_type();
|
||
|
||
if ( 'smart_coupon' === $discount_type ) {
|
||
$total = $order->get_total();
|
||
$discount_amount = ( is_object( $item ) && is_callable( array( $item, 'get_discount' ) ) ) ? $item->get_discount() : $this->get_order_item_meta( $item_id, 'discount_amount', true, true );
|
||
$smart_coupons_contribution = $this->get_post_meta( $order_id, 'smart_coupons_contribution', true, true );
|
||
$smart_coupons_contribution = ! empty( $smart_coupons_contribution ) ? $smart_coupons_contribution : array();
|
||
|
||
if ( ! empty( $smart_coupons_contribution ) && count( $smart_coupons_contribution ) > 0 && array_key_exists( $coupon_code, $smart_coupons_contribution ) ) {
|
||
$discount = $smart_coupons_contribution[ $coupon_code ];
|
||
} elseif ( ! empty( $discount_amount ) ) {
|
||
$discount = $discount_amount;
|
||
} else {
|
||
$discount = $this->sc_order_get_discount_amount( $total, $coupon, $order );
|
||
}
|
||
|
||
$discount = min( $total, $discount );
|
||
if ( is_object( $item ) && is_callable( array( $item, 'set_discount' ) ) ) {
|
||
$item->set_discount( $discount );
|
||
} else {
|
||
$item['discount_amount'] = $discount;
|
||
}
|
||
|
||
$order->set_total( $total - $discount );
|
||
|
||
$smart_coupons_contribution[ $coupon_code ] = $discount;
|
||
|
||
$this->update_post_meta( $order_id, 'smart_coupons_contribution', $smart_coupons_contribution, true, $order );
|
||
|
||
}
|
||
}
|
||
$pending_statuses = $this->get_pending_statuses();
|
||
if ( 'woocommerce_add_coupon_discount' === $post_action && $order->has_status( $pending_statuses ) && did_action( 'sc_after_order_calculate_discount_amount' ) <= 0 ) {
|
||
do_action( 'sc_after_order_calculate_discount_amount', $order_id );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Function to get discount amount for orders
|
||
*
|
||
* @param float $total Order total.
|
||
* @param WC_Coupon $coupon Coupon object.
|
||
* @param WC_Order $order Order object.
|
||
* @return float $discount
|
||
*/
|
||
public function sc_order_get_discount_amount( $total, $coupon, $order ) {
|
||
$discount = 0;
|
||
|
||
if ( is_a( $coupon, 'WC_Coupon' ) && is_a( $order, 'WC_Order' ) ) {
|
||
$discount_type = $coupon->get_discount_type();
|
||
$coupon_code = $coupon->get_code();
|
||
$coupon_product_ids = $coupon->get_product_ids();
|
||
$coupon_product_categories = $coupon->get_product_categories();
|
||
|
||
if ( 'smart_coupon' === $discount_type ) {
|
||
|
||
$coupon_amount = $this->get_amount( $coupon, true, $order );
|
||
|
||
$calculated_total = $total;
|
||
|
||
if ( count( $coupon_product_ids ) > 0 || count( $coupon_product_categories ) > 0 ) {
|
||
|
||
$discount = 0;
|
||
$line_totals = 0;
|
||
$line_taxes = 0;
|
||
$discounted_products = array();
|
||
|
||
$order_items = $order->get_items( 'line_item' );
|
||
|
||
foreach ( $order_items as $order_item_id => $order_item ) {
|
||
if ( $discount >= $coupon_amount ) {
|
||
break;
|
||
}
|
||
|
||
$product_id = ( is_object( $order_item ) && is_callable( array( $order_item, 'get_product_id' ) ) ) ? $order_item->get_product_id() : $order_item['product_id'];
|
||
$variation_id = ( is_object( $order_item ) && is_callable( array( $order_item, 'get_variation_id' ) ) ) ? $order_item->get_variation_id() : $order_item['variation_id'];
|
||
$line_total = ( is_object( $order_item ) && is_callable( array( $order_item, 'get_total' ) ) ) ? $order_item->get_total() : $order_item['line_total'];
|
||
$line_tax = ( is_object( $order_item ) && is_callable( array( $order_item, 'get_total_tax' ) ) ) ? $order_item->get_total_tax() : $order_item['line_tax'];
|
||
|
||
$product_cats = wc_get_product_cat_ids( $product_id );
|
||
|
||
if ( count( $coupon_product_categories ) > 0 ) {
|
||
|
||
$continue = false;
|
||
|
||
if ( ! empty( $order_item_id ) && ! empty( $discounted_products ) && is_array( $discounted_products ) && in_array( $order_item_id, $discounted_products, true ) ) {
|
||
$continue = true;
|
||
}
|
||
|
||
if ( ! $continue && count( array_intersect( $product_cats, $coupon_product_categories ) ) > 0 ) {
|
||
|
||
$discounted_products[] = ( ! empty( $order_item_id ) ) ? $order_item_id : '';
|
||
|
||
$line_totals += $line_total;
|
||
$line_taxes += $line_tax;
|
||
|
||
}
|
||
}
|
||
|
||
if ( count( $coupon_product_ids ) > 0 ) {
|
||
|
||
$continue = false;
|
||
|
||
if ( ! empty( $order_item_id ) && ! empty( $discounted_products ) && is_array( $discounted_products ) && in_array( $order_item_id, $discounted_products, true ) ) {
|
||
$continue = true;
|
||
}
|
||
|
||
if ( ! $continue && in_array( $product_id, $coupon_product_ids, true ) || in_array( $variation_id, $coupon_product_ids, true ) ) {
|
||
|
||
$discounted_products[] = ( ! empty( $order_item_id ) ) ? $order_item_id : '';
|
||
|
||
$line_totals += $line_total;
|
||
$line_taxes += $line_tax;
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
$calculated_total = round( ( $line_totals + $line_taxes ), wc_get_price_decimals() );
|
||
|
||
}
|
||
$discount = min( $calculated_total, $coupon_amount );
|
||
}
|
||
}
|
||
|
||
return $discount;
|
||
}
|
||
|
||
/**
|
||
* Function to apply Smart Coupons discount
|
||
*
|
||
* @param float $total Cart total.
|
||
* @param WC_Cart $cart Cart object.
|
||
* @param boolean $cart_contains_subscription Is cart contains subscription.
|
||
* @param string $calculation_type The calculation type.
|
||
* @return float $total
|
||
*/
|
||
public function smart_coupons_discounted_totals( $total = 0, $cart = null, $cart_contains_subscription = false, $calculation_type = '' ) {
|
||
|
||
if ( empty( $total ) ) {
|
||
return $total;
|
||
}
|
||
|
||
$applied_coupons = ( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'get_applied_coupons' ) ) ) ? WC()->cart->get_applied_coupons() : array();
|
||
|
||
$smart_coupon_credit_used = ( is_object( WC()->cart ) && isset( WC()->cart->smart_coupon_credit_used ) ) ? WC()->cart->smart_coupon_credit_used : array();
|
||
|
||
if ( ! empty( $applied_coupons ) ) {
|
||
foreach ( $applied_coupons as $code ) {
|
||
$request_wc_ajax = ( ! empty( $_REQUEST['wc-ajax'] ) ) ? wc_clean( wp_unslash( $_REQUEST['wc-ajax'] ) ) : ''; // phpcs:ignore
|
||
$ignore_ajax_action = array( 'update_order_review', 'checkout' );
|
||
if ( ! empty( $request_wc_ajax ) && in_array( $request_wc_ajax, $ignore_ajax_action, true ) && array_key_exists( $code, $smart_coupon_credit_used ) && true !== $cart_contains_subscription && ! isset( WC()->session->reload_checkout ) ) {
|
||
continue;
|
||
}
|
||
$coupon = new WC_Coupon( $code );
|
||
$discount = $this->sc_cart_get_discount_amount( $total, $coupon );
|
||
|
||
if ( ! empty( $discount ) ) {
|
||
$discount = min( $total, $discount );
|
||
$total = $total - $discount;
|
||
$this->manage_smart_coupon_credit_used( $coupon, $discount, $cart_contains_subscription, $calculation_type );
|
||
}
|
||
}
|
||
}
|
||
|
||
return $total;
|
||
}
|
||
|
||
/**
|
||
* Function to apply Smart Coupons discount after calculating tax
|
||
*
|
||
* @param WC_Cart $cart Cart object.
|
||
*/
|
||
public function smart_coupons_after_calculate_totals( $cart = null ) {
|
||
|
||
if ( empty( $cart ) || ! ( $cart instanceof WC_Cart ) ) {
|
||
return;
|
||
}
|
||
|
||
// Check if AvaTax is active by checking for its main function.
|
||
if ( function_exists( 'wc_avatax' ) ) {
|
||
$wc_avatax = wc_avatax();
|
||
if ( is_callable( array( $wc_avatax, 'get_tax_handler' ) ) ) {
|
||
$ava_tax_handler = $wc_avatax->get_tax_handler();
|
||
// Check if AvaTax is doing tax calculation.
|
||
if ( is_callable( array( $ava_tax_handler, 'is_available' ) ) && true === $ava_tax_handler->is_available() ) {
|
||
// Stop discount calculation till taxes from AvaTax have been calculated.
|
||
if ( is_checkout() && ! did_action( 'wc_avatax_after_checkout_tax_calculated' ) ) {
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
$cart_total = ( $this->is_wc_greater_than( '3.1.2' ) ) ? $cart->get_total( 'edit' ) : $cart->total;
|
||
|
||
if ( ! empty( $cart_total ) ) {
|
||
|
||
$stop_at = did_action( 'woocommerce_cart_reset' );
|
||
|
||
$stop_at = apply_filters( 'wc_sc_calculate_totals_stop_at', $stop_at, $cart );
|
||
|
||
if ( empty( $stop_at ) ) {
|
||
$stop_at = 1;
|
||
}
|
||
|
||
$cart_contains_subscription = WCS_SC_Compatibility::is_cart_contains_subscription();
|
||
$calculation_type = '';
|
||
|
||
if ( $cart_contains_subscription ) {
|
||
$stop_at++;
|
||
$calculation_type = WC_Subscriptions_Cart::get_calculation_type();
|
||
}
|
||
|
||
if ( did_action( 'smart_coupons_after_calculate_totals' ) > $stop_at ) {
|
||
return;
|
||
}
|
||
|
||
if ( 'recurring_total' === $calculation_type ) {
|
||
$total = $cart_total;
|
||
} else {
|
||
$total = $this->smart_coupons_discounted_totals( $cart_total, $cart, $cart_contains_subscription, $calculation_type );
|
||
}
|
||
|
||
if ( $this->is_wc_greater_than( '3.1.2' ) ) {
|
||
$cart->set_total( $total );
|
||
} else {
|
||
$cart->total = $total;
|
||
}
|
||
|
||
do_action( 'smart_coupons_after_calculate_totals' );
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* Function to do action 'smart_coupons_after_calculate_totals' since WooCommerce Services plugin triggers 'woocommerce_cart_reset' in its function for 'woocommerce_after_calculate_totals' action causing miscalculation in did_action( 'smart_coupons_after_calculate_totals' ) hook.
|
||
*/
|
||
public function woocommerce_cart_reset() {
|
||
|
||
$cart_reset_action_count = did_action( 'woocommerce_cart_reset' );
|
||
$sc_after_calculate_action_count = did_action( 'smart_coupons_after_calculate_totals' );
|
||
|
||
// This is to match counter for 'smart_coupons_after_calculate_totals' hook with 'woocommerce_cart_reset' counter since we are using these two counters to prevent store credit being appplied multiple times.
|
||
if ( $sc_after_calculate_action_count < $cart_reset_action_count ) {
|
||
do_action( 'smart_coupons_after_calculate_totals' );
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Function to calculate total cart contents.
|
||
* skip the product if the product is a bundled product.
|
||
*
|
||
* @since 4.32.0
|
||
* @return int
|
||
*/
|
||
public function get_cart_contents_count() {
|
||
$total_product = 0;
|
||
$cart_data = ( isset( WC()->cart ) && is_callable( array( WC()->cart, 'get_cart' ) ) ) ? WC()->cart->get_cart() : array();
|
||
if ( ! empty( $cart_data ) ) {
|
||
foreach ( $cart_data as $data ) {
|
||
// Skip bundled products.
|
||
if ( isset( $data['stamp'] ) && isset( $data['bundled_by'] ) ) {
|
||
continue;
|
||
}
|
||
$total_product++;
|
||
}
|
||
}
|
||
return $total_product;
|
||
}
|
||
|
||
/**
|
||
* Get coupon discount amount for percentage type coupon.
|
||
*
|
||
* @param float $discount Amount this coupon has discounted.
|
||
* @param float $discounting_amount Amount the coupon is being applied to.
|
||
* @param array|null $cart_item Cart item being discounted if applicable.
|
||
* @param bool $single True if discounting a single qty item, false if its the line.
|
||
* @param WC_Coupon $coupon Coupon object.
|
||
* @return float $discount
|
||
*/
|
||
public function get_coupon_discount_amount( $discount = 0, $discounting_amount = 0, $cart_item = array(), $single = false, $coupon = object ) {
|
||
|
||
if ( is_a( $coupon, 'WC_Coupon' ) ) {
|
||
|
||
if ( is_object( $coupon ) && is_callable( array( $coupon, 'is_valid' ) ) && $coupon->is_valid() && is_callable( array( $coupon, 'is_type' ) ) && $coupon->is_type( 'percent' ) ) {
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$coupon_id = ( is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
|
||
} else {
|
||
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
|
||
}
|
||
|
||
if ( empty( $coupon_id ) ) {
|
||
return $discount;
|
||
}
|
||
|
||
$order = ( is_a( $cart_item, 'WC_Order_Item' ) && is_callable( array( $cart_item, 'get_order' ) ) ) ? $cart_item->get_order() : null;
|
||
|
||
$max_discount = $this->get_post_meta( $coupon_id, 'wc_sc_max_discount', true, true, $order );
|
||
|
||
if ( ! empty( $max_discount ) && is_numeric( $max_discount ) ) {
|
||
|
||
$coupon_product_ids = ( is_callable( array( $coupon, 'get_product_ids' ) ) ) ? $coupon->get_product_ids() : array();
|
||
$coupon_excluded_product_ids = ( is_callable( array( $coupon, 'get_excluded_product_ids' ) ) ) ? $coupon->get_excluded_product_ids() : array();
|
||
$coupon_category_ids = ( is_callable( array( $coupon, 'get_product_categories' ) ) ) ? $coupon->get_product_categories() : array();
|
||
$coupon_excluded_category_ids = ( is_callable( array( $coupon, 'get_excluded_product_categories' ) ) ) ? $coupon->get_excluded_product_categories() : array();
|
||
$cart_items_subtotal = 0;
|
||
$cart_contents_count = 0;
|
||
$max_discount_name = 'wc_sc_max_discount_data';
|
||
$inc_tax = wc_prices_include_tax();
|
||
$is_restricted = count( $coupon_product_ids ) > 0 || count( $coupon_excluded_product_ids ) > 0 || count( $coupon_category_ids ) > 0 || count( $coupon_excluded_category_ids ) > 0;
|
||
$is_restricted = apply_filters(
|
||
'wc_sc_is_coupon_restriction_available',
|
||
$is_restricted,
|
||
array(
|
||
'source' => $this,
|
||
'discount' => $discount,
|
||
'discounting_amount' => $discounting_amount,
|
||
'cart_item' => $cart_item,
|
||
'single' => $single,
|
||
'coupon_object' => $coupon,
|
||
)
|
||
);
|
||
|
||
if ( is_a( $cart_item, 'WC_Order_Item_Product' ) ) {
|
||
$order = $wc_cart_or_order_object = ( is_callable( array( $cart_item, 'get_order' ) ) ) ? $cart_item->get_order() : null; // phpcs:ignore
|
||
$wc_order_id = ( is_callable( array( $cart_item, 'get_order_id' ) ) ) ? $cart_item->get_order_id() : 0;
|
||
if ( empty( $wc_order_id ) ) {
|
||
return $discount;
|
||
}
|
||
$order_line_items = array();
|
||
if ( is_a( $order, 'WC_Order' ) ) {
|
||
$cart_items_subtotal = ( is_callable( array( $order, 'get_subtotal' ) ) ) ? $order->get_subtotal() : 0;
|
||
$order_line_items = ( is_callable( array( $order, 'get_items' ) ) ) ? $order->get_items() : array();
|
||
}
|
||
|
||
$max_discount_name = 'wc_sc_max_discount_data_for_' . $wc_order_id;
|
||
if ( ! empty( $order_line_items ) ) {
|
||
foreach ( $order_line_items as $order_line_item ) {
|
||
$cart_contents_count++;
|
||
}
|
||
}
|
||
|
||
$max_discount_data = function_exists( 'get_transient' ) ? get_transient( $max_discount_name ) : array();
|
||
} else {
|
||
$wc_cart = $wc_cart_or_order_object = ! empty( WC()->cart ) ? WC()->cart : null; // phpcs:ignore
|
||
$wc_session = ! empty( WC()->session ) ? WC()->session : null;
|
||
if ( ! is_a( $wc_cart, 'WC_Cart' ) ) {
|
||
return $discount;
|
||
}
|
||
if ( true === $inc_tax ) {
|
||
$cart_items_subtotal = ! empty( $wc_cart->subtotal ) ? $wc_cart->subtotal : 0;
|
||
} else {
|
||
$cart_items_subtotal = ! empty( $wc_cart->subtotal_ex_tax ) ? $wc_cart->subtotal_ex_tax : 0;
|
||
}
|
||
|
||
$max_discount_data = ( ! empty( $wc_session ) && is_a( $wc_session, 'WC_Session' ) && is_callable( array( $wc_session, 'get' ) ) ) ? $wc_session->get( $max_discount_name ) : array();
|
||
|
||
$cart_contents_count = $this->get_cart_contents_count();
|
||
}
|
||
|
||
$is_update_valid_item_count = false;
|
||
|
||
if ( empty( $max_discount_data ) || ! is_array( $max_discount_data ) ) {
|
||
$max_discount_data = array();
|
||
}
|
||
|
||
if ( empty( $max_discount_data[ $coupon_id ] ) || ! is_array( $max_discount_data[ $coupon_id ] ) ) {
|
||
$max_discount_data[ $coupon_id ] = array();
|
||
$is_update_valid_item_count = true;
|
||
$max_discount_data[ $coupon_id ]['amount'] = $max_discount;
|
||
$max_discount_data[ $coupon_id ]['count'] = $cart_contents_count;
|
||
}
|
||
|
||
if ( true === $is_restricted && class_exists( 'WC_Discounts' ) && ! empty( $wc_cart_or_order_object ) ) {
|
||
|
||
$wc_discounts = new WC_Discounts( $wc_cart_or_order_object );
|
||
$items_to_validate = array();
|
||
|
||
if ( is_callable( array( $wc_discounts, 'get_items_to_validate' ) ) ) {
|
||
$items_to_validate = $wc_discounts->get_items_to_validate();
|
||
} elseif ( is_callable( array( $wc_discounts, 'get_items' ) ) ) {
|
||
$items_to_validate = $wc_discounts->get_items();
|
||
} elseif ( ! empty( $wc_discounts->items ) && is_array( $wc_discounts->items ) ) {
|
||
$items_to_validate = $wc_discounts->items;
|
||
}
|
||
|
||
if ( is_array( $items_to_validate ) ) {
|
||
$valid_product_count = 0;
|
||
foreach ( $items_to_validate as $item ) {
|
||
$item_to_apply = clone $item; // Clone the item so changes to wc_discounts item do not affect the originals.
|
||
$valid_product_quantity = ( ! empty( $item_to_apply->quantity ) ) ? intval( $item_to_apply->quantity ) : 0;
|
||
$product = ( ! empty( $item_to_apply->product ) ) ? $item_to_apply->product : null;
|
||
$item_to_apply_object = ( ! empty( $item_to_apply->object ) ) ? $item_to_apply->object : null;
|
||
|
||
if ( 0 === $wc_discounts->get_discounted_price_in_cents( $item_to_apply ) || 0 >= $valid_product_quantity ) {
|
||
continue;
|
||
}
|
||
|
||
if ( ! $coupon->is_valid_for_product( $product, $item_to_apply_object ) && ! $coupon->is_valid_for_cart() ) {
|
||
continue;
|
||
}
|
||
|
||
// Increment if the product is not a bundled product.
|
||
$valid_product_count = ( isset( $item_to_apply_object['stamp'] ) && isset( $item_to_apply_object['bundled_by'] ) ) ? $valid_product_count : $valid_product_count + 1;
|
||
$line_subtotal = ! empty( $item_to_apply_object['line_subtotal'] ) ? intval( $item_to_apply_object['line_subtotal'] ) : 0;
|
||
if ( true === $inc_tax ) {
|
||
$line_subtotal_tax = ! empty( $item_to_apply_object['line_subtotal_tax'] ) ? intval( $item_to_apply_object['line_subtotal_tax'] ) : 0;
|
||
$cart_items_subtotal += $line_subtotal + $line_subtotal_tax;
|
||
} else {
|
||
$cart_items_subtotal += $line_subtotal;
|
||
}
|
||
}
|
||
|
||
if ( true === $is_update_valid_item_count ) {
|
||
$max_discount_data[ $coupon_id ]['count'] = $valid_product_count;
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( 0 !== $cart_items_subtotal ) {
|
||
|
||
$max_discount = ! empty( $max_discount_data[ $coupon_id ]['amount'] ) ? $max_discount_data[ $coupon_id ]['amount'] : 0;
|
||
if ( $max_discount < 0 ) {
|
||
$max_discount = 0;
|
||
}
|
||
|
||
$discount = min( $max_discount, $discount );
|
||
|
||
if ( ! empty( $max_discount ) ) {
|
||
$max_discount_data[ $coupon_id ]['amount'] -= $discount;
|
||
}
|
||
|
||
$max_discount_data[ $coupon_id ]['count']--;
|
||
|
||
if ( 0 >= $max_discount_data[ $coupon_id ]['count'] ) {
|
||
unset( $max_discount_data[ $coupon_id ] );
|
||
}
|
||
if ( 'wc_sc_max_discount_data' === $max_discount_name ) {
|
||
if ( ! empty( $wc_session ) && is_a( $wc_session, 'WC_Session' ) && is_callable( array( $wc_session, 'set' ) ) ) {
|
||
$wc_session->set( $max_discount_name, $max_discount_data );
|
||
}
|
||
} elseif ( function_exists( 'set_transient' ) ) {
|
||
set_transient( $max_discount_name, $max_discount_data, DAY_IN_SECONDS );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return $discount;
|
||
}
|
||
|
||
/**
|
||
* Function to set default values to postmeta fields
|
||
*
|
||
* @param array $defaults Existing postmeta defaults.
|
||
* @return array
|
||
*/
|
||
public function postmeta_defaults( $defaults = array() ) {
|
||
|
||
if ( $this->is_wc_gte_32() ) {
|
||
$defaults['wc_sc_expiry_time'] = '';
|
||
}
|
||
|
||
return $defaults;
|
||
}
|
||
|
||
/**
|
||
* Function to get discount amount
|
||
*
|
||
* @param float $total The total.
|
||
* @param WC_Coupon $coupon The coupon object.
|
||
* @return float $discount
|
||
*/
|
||
public function sc_cart_get_discount_amount( $total = 0, $coupon = '' ) {
|
||
|
||
$discount = 0;
|
||
|
||
if ( is_a( $coupon, 'WC_Coupon' ) ) {
|
||
|
||
if ( $coupon->is_valid() && $coupon->is_type( 'smart_coupon' ) ) {
|
||
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$coupon_code = $coupon->get_code();
|
||
$coupon_product_ids = $coupon->get_product_ids();
|
||
$coupon_product_categories = $coupon->get_product_categories();
|
||
} else {
|
||
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
|
||
$coupon_product_ids = ( ! empty( $coupon->product_ids ) ) ? $coupon->product_ids : array();
|
||
$coupon_product_categories = ( ! empty( $coupon->product_categories ) ) ? $coupon->product_categories : array();
|
||
}
|
||
|
||
$coupon_amount = $this->get_amount( $coupon, true );
|
||
|
||
$calculated_total = $total;
|
||
|
||
if ( count( $coupon_product_ids ) > 0 || count( $coupon_product_categories ) > 0 ) {
|
||
|
||
$discount = 0;
|
||
$line_totals = 0;
|
||
$line_taxes = 0;
|
||
$discounted_products = array();
|
||
|
||
foreach ( WC()->cart->cart_contents as $cart_item_key => $product ) {
|
||
|
||
if ( $discount >= $coupon_amount ) {
|
||
break;
|
||
}
|
||
|
||
$product_cats = wc_get_product_cat_ids( $product['product_id'] );
|
||
|
||
if ( count( $coupon_product_categories ) > 0 ) {
|
||
|
||
$continue = false;
|
||
|
||
if ( ! empty( $cart_item_key ) && ! empty( $discounted_products ) && is_array( $discounted_products ) && in_array( $cart_item_key, $discounted_products, true ) ) {
|
||
$continue = true;
|
||
}
|
||
|
||
if ( ! $continue && count( array_intersect( $product_cats, $coupon_product_categories ) ) > 0 ) {
|
||
|
||
$discounted_products[] = ( ! empty( $cart_item_key ) ) ? $cart_item_key : '';
|
||
|
||
$line_totals += $product['line_total'];
|
||
$line_taxes += $product['line_tax'];
|
||
|
||
}
|
||
}
|
||
|
||
if ( count( $coupon_product_ids ) > 0 ) {
|
||
|
||
$continue = false;
|
||
|
||
if ( ! empty( $cart_item_key ) && ! empty( $discounted_products ) && is_array( $discounted_products ) && in_array( $cart_item_key, $discounted_products, true ) ) {
|
||
$continue = true;
|
||
}
|
||
|
||
if ( ! $continue && in_array( $product['product_id'], $coupon_product_ids, true ) || in_array( $product['variation_id'], $coupon_product_ids, true ) || in_array( $product['data']->get_parent(), $coupon_product_ids, true ) ) {
|
||
|
||
$discounted_products[] = ( ! empty( $cart_item_key ) ) ? $cart_item_key : '';
|
||
|
||
$line_totals += $product['line_total'];
|
||
$line_taxes += $product['line_tax'];
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
$calculated_total = round( ( $line_totals + $line_taxes ), wc_get_price_decimals() );
|
||
|
||
}
|
||
|
||
$discount = min( $calculated_total, $coupon_amount );
|
||
}
|
||
}
|
||
|
||
return $discount;
|
||
}
|
||
|
||
/**
|
||
* Function to manage store credit used
|
||
*
|
||
* @param WC_Coupon $coupon The coupon object.
|
||
* @param float $discount The discount.
|
||
* @param bool $cart_contains_subscription Is cart contains subscription.
|
||
* @param string $calculation_type Calculation type.
|
||
*/
|
||
public function manage_smart_coupon_credit_used( $coupon = '', $discount = 0, $cart_contains_subscription = false, $calculation_type = '' ) {
|
||
if ( is_object( $coupon ) && $coupon instanceof WC_Coupon ) {
|
||
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$coupon_code = ( is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
|
||
} else {
|
||
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
|
||
}
|
||
|
||
if ( $cart_contains_subscription ) {
|
||
if ( WCS_SC_Compatibility::is_wcs_gte( '2.0.10' ) ) {
|
||
if ( $this->is_wc_greater_than( '3.1.2' ) ) {
|
||
$coupon_discount_totals = ( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'get_coupon_discount_totals' ) ) ) ? WC()->cart->get_coupon_discount_totals() : array();
|
||
if ( ! is_array( $coupon_discount_totals ) ) {
|
||
$coupon_discount_totals = array();
|
||
}
|
||
if ( empty( $coupon_discount_totals[ $coupon_code ] ) ) {
|
||
$coupon_discount_totals[ $coupon_code ] = $discount;
|
||
} else {
|
||
$coupon_discount_totals[ $coupon_code ] += $discount;
|
||
}
|
||
( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'set_coupon_discount_totals' ) ) ) ? WC()->cart->set_coupon_discount_totals( $coupon_discount_totals ) : '';
|
||
} else {
|
||
$coupon_discount_amounts = ( is_object( WC()->cart ) && isset( WC()->cart->coupon_discount_amounts ) ) ? WC()->cart->coupon_discount_amounts : array();
|
||
if ( ! is_array( $coupon_discount_amounts ) ) {
|
||
$coupon_discount_amounts = array();
|
||
}
|
||
if ( empty( $coupon_discount_amounts[ $coupon_code ] ) ) {
|
||
$coupon_discount_amounts[ $coupon_code ] = $discount;
|
||
} else {
|
||
$coupon_discount_amounts[ $coupon_code ] += $discount;
|
||
}
|
||
WC()->cart->coupon_discount_amounts = $coupon_discount_amounts;
|
||
}
|
||
} elseif ( WCS_SC_Compatibility::is_wcs_gte( '2.0.0' ) ) {
|
||
WC_Subscriptions_Coupon::increase_coupon_discount_amount( WC()->cart, $coupon_code, $discount );
|
||
} else {
|
||
WC_Subscriptions_Cart::increase_coupon_discount_amount( $coupon_code, $discount );
|
||
}
|
||
} else {
|
||
if ( $this->is_wc_greater_than( '3.1.2' ) ) {
|
||
$coupon_discount_totals = ( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'get_coupon_discount_totals' ) ) ) ? WC()->cart->get_coupon_discount_totals() : array();
|
||
if ( ! is_array( $coupon_discount_totals ) ) {
|
||
$coupon_discount_totals = array();
|
||
}
|
||
if ( empty( $coupon_discount_totals[ $coupon_code ] ) ) {
|
||
$coupon_discount_totals[ $coupon_code ] = $discount;
|
||
} else {
|
||
$coupon_discount_totals[ $coupon_code ] += $discount;
|
||
}
|
||
( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'set_coupon_discount_totals' ) ) ) ? WC()->cart->set_coupon_discount_totals( $coupon_discount_totals ) : '';
|
||
} else {
|
||
$coupon_discount_amounts = ( is_object( WC()->cart ) && isset( WC()->cart->coupon_discount_amounts ) ) ? WC()->cart->coupon_discount_amounts : array();
|
||
if ( ! is_array( $coupon_discount_amounts ) ) {
|
||
$coupon_discount_amounts = array();
|
||
}
|
||
if ( empty( $coupon_discount_amounts[ $coupon_code ] ) ) {
|
||
$coupon_discount_amounts[ $coupon_code ] = $discount;
|
||
} else {
|
||
$coupon_discount_amounts[ $coupon_code ] += $discount;
|
||
}
|
||
WC()->cart->coupon_discount_amounts = $coupon_discount_amounts;
|
||
}
|
||
}
|
||
|
||
if ( isset( WC()->session->reload_checkout ) ) { // reload_checkout is triggered when customer is registered from checkout.
|
||
unset( WC()->cart->smart_coupon_credit_used ); // reset store credit used data for re-calculation.
|
||
}
|
||
|
||
$smart_coupon_credit_used = ( is_object( WC()->cart ) && isset( WC()->cart->smart_coupon_credit_used ) ) ? WC()->cart->smart_coupon_credit_used : array();
|
||
|
||
if ( ! is_array( $smart_coupon_credit_used ) ) {
|
||
$smart_coupon_credit_used = array();
|
||
}
|
||
if ( empty( $smart_coupon_credit_used[ $coupon_code ] ) || ( $cart_contains_subscription && ( 'combined_total' === $calculation_type || 'sign_up_fee_total' === $calculation_type ) ) ) {
|
||
$smart_coupon_credit_used[ $coupon_code ] = $discount;
|
||
} else {
|
||
$smart_coupon_credit_used[ $coupon_code ] += $discount;
|
||
}
|
||
WC()->cart->smart_coupon_credit_used = $smart_coupon_credit_used;
|
||
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Apply store credit discount in order during recalculation
|
||
*
|
||
* @param float $total The total.
|
||
* @param WC_Order $order The order object.
|
||
* @return float $total
|
||
*/
|
||
public function smart_coupons_order_discounted_total( $total = 0, $order = null ) {
|
||
|
||
if ( ! $this->is_wc_gte_30() ) {
|
||
|
||
$is_proceed = check_ajax_referer( 'calc-totals', 'security', false );
|
||
|
||
if ( ! $is_proceed ) {
|
||
return $total;
|
||
}
|
||
|
||
$called_by = ( ! empty( $_POST['action'] ) ) ? wc_clean( wp_unslash( $_POST['action'] ) ) : ''; // phpcs:ignore
|
||
|
||
if ( 'woocommerce_calc_line_taxes' !== $called_by ) {
|
||
return $total;
|
||
}
|
||
}
|
||
|
||
if ( empty( $order ) ) {
|
||
return $total;
|
||
}
|
||
|
||
$coupons = ( is_object( $order ) && is_callable( array( $order, 'get_items' ) ) ) ? $order->get_items( 'coupon' ) : array();
|
||
|
||
if ( ! empty( $coupons ) ) {
|
||
foreach ( $coupons as $coupon ) {
|
||
$code = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
|
||
if ( empty( $code ) ) {
|
||
continue;
|
||
}
|
||
$_coupon = new WC_Coupon( $code );
|
||
$discount_type = ( is_object( $_coupon ) && is_callable( array( $_coupon, 'get_discount_type' ) ) ) ? $_coupon->get_discount_type() : '';
|
||
if ( ! empty( $discount_type ) && 'smart_coupon' === $discount_type ) {
|
||
$discount = $this->get_amount( $_coupon, true, $order );
|
||
$applied_discount = min( $total, $discount );
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$coupon->set_discount( $applied_discount );
|
||
$coupon->save();
|
||
}
|
||
$total = $total - $applied_discount;
|
||
}
|
||
}
|
||
}
|
||
|
||
return $total;
|
||
}
|
||
|
||
/**
|
||
* Add tool for clearing cache
|
||
*
|
||
* @param array $tools Existing tools.
|
||
* @return array $tools
|
||
*/
|
||
public function clear_cache_tool( $tools = array() ) {
|
||
|
||
$tools['wc_sc_clear_cache'] = array(
|
||
'name' => __( 'WooCommerce Smart Coupons Cache', 'woocommerce-smart-coupons' ),
|
||
'button' => __( 'Clear Smart Coupons Cache', 'woocommerce-smart-coupons' ),
|
||
'desc' => __( 'This tool will clear the cache created by WooCommerce Smart Coupons.', 'woocommerce-smart-coupons' ),
|
||
'callback' => array(
|
||
$this,
|
||
'clear_cache',
|
||
),
|
||
);
|
||
|
||
return $tools;
|
||
}
|
||
|
||
/**
|
||
* Clear cache
|
||
*
|
||
* @return string $message
|
||
*/
|
||
public function clear_cache() {
|
||
|
||
$message = ( is_callable( array( 'WC_SC_Act_Deact', 'clear_cache' ) ) ) ? WC_SC_Act_Deact::clear_cache() : '';
|
||
|
||
return $message;
|
||
}
|
||
|
||
/**
|
||
* WooCommerce Checkout Update Order Review
|
||
*
|
||
* @param array $post_data The post data.
|
||
*/
|
||
public function woocommerce_checkout_update_order_review( $post_data = array() ) {
|
||
|
||
wp_parse_str( $post_data, $posted_data );
|
||
|
||
if ( ! empty( $posted_data['billing_email'] ) ) {
|
||
$applied_coupons = ( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'get_applied_coupons' ) ) ) ? WC()->cart->get_applied_coupons() : array();
|
||
if ( ! empty( $applied_coupons ) ) {
|
||
if ( empty( $_REQUEST['billing_email'] ) ) { // phpcs:ignore
|
||
$_REQUEST['billing_email'] = $posted_data['billing_email'];
|
||
}
|
||
foreach ( $applied_coupons as $coupon_code ) {
|
||
$coupon = new WC_Coupon( $coupon_code );
|
||
$is_valid = $this->is_user_usage_limit_valid( true, $coupon );
|
||
if ( true !== $is_valid ) {
|
||
WC()->cart->remove_coupon( $coupon_code );
|
||
/* translators: The coupon code */
|
||
wc_add_notice( sprintf( __( 'Coupon %s is valid for a new user only, hence removed.', 'woocommerce-smart-coupons' ), '<code>' . $coupon_code . '</code>' ), 'error' );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Function to return validity of Store Credit / Gift Certificate
|
||
*
|
||
* @param boolean $valid Coupon validity.
|
||
* @param WC_Coupon $coupon Coupon object.
|
||
* @param WC_Discounts $discounts Discounts object.
|
||
* @return boolean $valid TRUE if smart coupon valid, FALSE otherwise
|
||
*/
|
||
public function is_smart_coupon_valid( $valid, $coupon, $discounts = null ) {
|
||
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$discount_type = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
|
||
$coupon_code = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
|
||
} else {
|
||
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
|
||
$coupon_code = ( ! empty( $coupon->code ) ) ? $coupon->code : '';
|
||
}
|
||
|
||
$coupon_amount = $this->get_amount( $coupon, true );
|
||
|
||
if ( 'smart_coupon' !== $discount_type ) {
|
||
return $valid;
|
||
}
|
||
|
||
$applied_coupons = ( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'get_applied_coupons' ) ) ) ? WC()->cart->get_applied_coupons() : array();
|
||
|
||
if ( empty( $applied_coupons ) || ( ! empty( $applied_coupons ) && ! in_array( $coupon_code, $applied_coupons, true ) ) ) {
|
||
return $valid;
|
||
}
|
||
|
||
if ( is_wc_endpoint_url( 'order-received' ) ) {
|
||
return $valid;
|
||
}
|
||
|
||
$is_valid_coupon_amount = ( $coupon_amount <= 0 ) ? false : true;
|
||
|
||
$is_valid_coupon_amount = apply_filters(
|
||
'wc_sc_validate_coupon_amount',
|
||
$is_valid_coupon_amount,
|
||
array(
|
||
'coupon' => $coupon,
|
||
'discounts' => $discounts,
|
||
'coupon_amount' => $coupon_amount,
|
||
'discount_type' => $discount_type,
|
||
'coupon_code' => $coupon_code,
|
||
)
|
||
);
|
||
|
||
if ( $valid && ! $is_valid_coupon_amount ) {
|
||
WC()->cart->remove_coupon( $coupon_code );
|
||
/* translators: The coupon code */
|
||
wc_add_notice( sprintf( __( 'Coupon removed. There is no credit remaining in %s.', 'woocommerce-smart-coupons' ), '<strong>' . $coupon_code . '</strong>' ), 'error' );
|
||
return false;
|
||
}
|
||
|
||
return $valid;
|
||
}
|
||
|
||
/**
|
||
* Strict check if user is valid as per usage limit
|
||
*
|
||
* @param boolean $is_valid Is valid.
|
||
* @param WC_Coupon $coupon The coupon object.
|
||
* @param WC_Discounts $discounts The discounts object.
|
||
* @return boolean
|
||
* @throws Exception When coupon is not valid as per the usage limit.
|
||
*/
|
||
public function is_user_usage_limit_valid( $is_valid = false, $coupon = null, $discounts = null ) {
|
||
|
||
if ( is_admin() && ( ! defined( 'DOING_AJAX' ) || DOING_AJAX !== true ) ) {
|
||
return $is_valid;
|
||
}
|
||
|
||
if ( true !== $is_valid ) {
|
||
return $is_valid;
|
||
}
|
||
|
||
global $wpdb;
|
||
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$coupon_id = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
|
||
} else {
|
||
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
|
||
}
|
||
|
||
$for_new_user = ( $this->is_callable( $coupon, 'get_meta' ) ) ? $coupon->get_meta( 'sc_restrict_to_new_user' ) : get_post_meta( $coupon_id, 'sc_restrict_to_new_user', true );
|
||
|
||
if ( 'yes' === $for_new_user ) {
|
||
|
||
$failed_notice = __( 'This coupon is valid for the first order only.', 'woocommerce-smart-coupons' );
|
||
|
||
$user_id_1 = 0;
|
||
$user_id_2 = 0;
|
||
$user_id_3 = 0;
|
||
|
||
$current_user = wp_get_current_user();
|
||
|
||
$email = ( ! empty( $current_user->data->user_email ) ) ? $current_user->data->user_email : '';
|
||
|
||
$email = ( ! empty( $_REQUEST['billing_email'] ) ) ? sanitize_email( wp_unslash( $_REQUEST['billing_email'] ) ) : $email; // phpcs:ignore
|
||
|
||
$valid_order_statuses = get_option( 'wc_sc_valid_order_statuses_for_coupon_auto_generation', array() );
|
||
$statuses_placeholder = array();
|
||
if ( ! empty( $valid_order_statuses ) ) {
|
||
$valid_order_statuses = array_map(
|
||
function( $status ) {
|
||
return 'wc-' . $status;
|
||
},
|
||
$valid_order_statuses
|
||
);
|
||
$how_many_statuses = count( $valid_order_statuses );
|
||
$statuses_placeholder = array_fill( 0, $how_many_statuses, '%s' );
|
||
}
|
||
|
||
if ( ! empty( $email ) && is_email( $email ) ) {
|
||
|
||
$order_id = wp_cache_get( 'wc_sc_order_id_by_billing_email_' . sanitize_key( $email ), 'woocommerce_smart_coupons' );
|
||
|
||
if ( false === $order_id ) {
|
||
$query = $wpdb->prepare(
|
||
"SELECT ID
|
||
FROM $wpdb->posts AS p
|
||
LEFT JOIN $wpdb->postmeta AS pm
|
||
ON ( p.ID = pm.post_id AND pm.meta_key = %s )
|
||
WHERE p.post_type = %s
|
||
AND pm.meta_value = %s",
|
||
'_billing_email',
|
||
'shop_order',
|
||
$email
|
||
);
|
||
|
||
if ( ! empty( $valid_order_statuses ) && ! empty( $statuses_placeholder ) ) {
|
||
// phpcs:disable
|
||
$query .= $wpdb->prepare(
|
||
' AND p.post_status IN (' . implode( ',', $statuses_placeholder ) . ')',
|
||
$valid_order_statuses
|
||
);
|
||
// phpcs:enable
|
||
}
|
||
|
||
$order_id = $wpdb->get_var( $query ); // phpcs:ignore
|
||
|
||
wp_cache_set( 'wc_sc_order_id_by_billing_email_' . sanitize_key( $email ), $order_id, 'woocommerce_smart_coupons' );
|
||
$this->maybe_add_cache_key( 'wc_sc_order_id_by_billing_email_' . sanitize_key( $email ) );
|
||
}
|
||
|
||
if ( ! empty( $order_id ) ) {
|
||
if ( defined( 'WC_DOING_AJAX' ) && WC_DOING_AJAX === true ) {
|
||
$is_valid = false;
|
||
} else {
|
||
throw new Exception( $failed_notice );
|
||
}
|
||
}
|
||
|
||
$user_id_1 = wp_cache_get( 'wc_sc_user_id_by_user_email_' . sanitize_key( $email ), 'woocommerce_smart_coupons' );
|
||
if ( false === $user_id_1 ) {
|
||
$user_id_1 = $wpdb->get_var( // phpcs:ignore
|
||
$wpdb->prepare(
|
||
"SELECT ID
|
||
FROM {$wpdb->base_prefix}users
|
||
WHERE user_email = %s",
|
||
$email
|
||
)
|
||
);
|
||
wp_cache_set( 'wc_sc_user_id_by_user_email_' . sanitize_key( $email ), $user_id_1, 'woocommerce_smart_coupons' );
|
||
$this->maybe_add_cache_key( 'wc_sc_user_id_by_user_email_' . sanitize_key( $email ) );
|
||
}
|
||
|
||
$user_id_2 = wp_cache_get( 'wc_sc_user_id_by_billing_email_' . sanitize_key( $email ), 'woocommerce_smart_coupons' );
|
||
if ( false === $user_id_2 ) {
|
||
$user_id_2 = $wpdb->get_var( // phpcs:ignore
|
||
$wpdb->prepare(
|
||
"SELECT user_id
|
||
FROM {$wpdb->base_prefix}usermeta
|
||
WHERE meta_key = %s
|
||
AND meta_value = %s",
|
||
'billing_email',
|
||
$email
|
||
)
|
||
);
|
||
wp_cache_set( 'wc_sc_user_id_by_billing_email_' . sanitize_key( $email ), $user_id_2, 'woocommerce_smart_coupons' );
|
||
$this->maybe_add_cache_key( 'wc_sc_user_id_by_billing_email_' . sanitize_key( $email ) );
|
||
}
|
||
}
|
||
|
||
$user_id_3 = get_current_user_id();
|
||
|
||
$user_ids = array( $user_id_1, $user_id_2, $user_id_3 );
|
||
$user_ids = array_unique( array_filter( $user_ids ) );
|
||
|
||
if ( ! empty( $user_ids ) ) {
|
||
|
||
$unique_user_ids = array_unique( $user_ids );
|
||
|
||
$order_id = wp_cache_get( 'wc_sc_order_for_user_id_' . implode( '_', $unique_user_ids ), 'woocommerce_smart_coupons' );
|
||
|
||
if ( false === $order_id ) {
|
||
$query = $wpdb->prepare(
|
||
"SELECT ID
|
||
FROM $wpdb->posts AS p
|
||
LEFT JOIN $wpdb->postmeta AS pm
|
||
ON ( p.ID = pm.post_id AND pm.meta_key = %s )
|
||
WHERE p.post_type = %s",
|
||
'_customer_user',
|
||
'shop_order'
|
||
);
|
||
|
||
if ( ! empty( $valid_order_statuses ) && ! empty( $statuses_placeholder ) ) {
|
||
// phpcs:disable
|
||
$query .= $wpdb->prepare(
|
||
' AND p.post_status IN (' . implode( ',', $statuses_placeholder ) . ')',
|
||
$valid_order_statuses
|
||
);
|
||
// phpcs:enable
|
||
}
|
||
|
||
$how_many_user_ids = count( $user_ids );
|
||
$id_placeholder = array_fill( 0, $how_many_user_ids, '%s' );
|
||
|
||
// phpcs:disable
|
||
$query .= $wpdb->prepare(
|
||
' AND pm.meta_value IN (' . implode( ',', $id_placeholder ) . ')',
|
||
$user_ids
|
||
);
|
||
// phpcs:enable
|
||
|
||
$order_id = $wpdb->get_var( $query ); // phpcs:ignore
|
||
|
||
wp_cache_set( 'wc_sc_order_for_user_id_' . implode( '_', $unique_user_ids ), $order_id, 'woocommerce_smart_coupons' );
|
||
$this->maybe_add_cache_key( 'wc_sc_order_for_user_id_' . implode( '_', $unique_user_ids ) );
|
||
}
|
||
|
||
if ( ! empty( $order_id ) ) {
|
||
if ( defined( 'WC_DOING_AJAX' ) && WC_DOING_AJAX === true ) {
|
||
$is_valid = false;
|
||
} else {
|
||
throw new Exception( $failed_notice );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return $is_valid;
|
||
}
|
||
|
||
/**
|
||
* Locate template for Smart Coupons
|
||
*
|
||
* @param string $template_name The template name.
|
||
* @param mixed $template Default template.
|
||
* @return mixed $template
|
||
*/
|
||
public function locate_template_for_smart_coupons( $template_name = '', $template = '' ) {
|
||
|
||
$default_path = untrailingslashit( plugin_dir_path( WC_SC_PLUGIN_FILE ) ) . '/templates/';
|
||
|
||
$plugin_base_dir = substr( plugin_basename( WC_SC_PLUGIN_FILE ), 0, strpos( plugin_basename( WC_SC_PLUGIN_FILE ), '/' ) + 1 );
|
||
|
||
// Look within passed path within the theme - this is priority.
|
||
$template = locate_template(
|
||
array(
|
||
'woocommerce/' . $plugin_base_dir . $template_name,
|
||
$plugin_base_dir . $template_name,
|
||
$template_name,
|
||
)
|
||
);
|
||
|
||
// Get default template.
|
||
if ( ! $template ) {
|
||
$template = $default_path . $template_name;
|
||
}
|
||
|
||
return $template;
|
||
}
|
||
|
||
/**
|
||
* Function to get template base directory for Smart Coupons' email templates
|
||
*
|
||
* @param string $template_name Template name.
|
||
* @return string $template_base_dir Base directory for Smart Coupons' email templates.
|
||
*/
|
||
public function get_template_base_dir( $template_name = '' ) {
|
||
|
||
$template_base_dir = '';
|
||
$plugin_base_dir = substr( plugin_basename( WC_SC_PLUGIN_FILE ), 0, strpos( plugin_basename( WC_SC_PLUGIN_FILE ), '/' ) + 1 );
|
||
$wc_sc_base_dir = 'woocommerce/' . $plugin_base_dir;
|
||
|
||
// First locate the template in woocommerce/woocommerce-smart-coupons folder of active theme.
|
||
$template = locate_template(
|
||
array(
|
||
$wc_sc_base_dir . $template_name,
|
||
)
|
||
);
|
||
|
||
if ( ! empty( $template ) ) {
|
||
$template_base_dir = $wc_sc_base_dir;
|
||
} else {
|
||
// If not found then locate the template in woocommerce-smart-coupons folder of active theme.
|
||
$template = locate_template(
|
||
array(
|
||
$plugin_base_dir . $template_name,
|
||
)
|
||
);
|
||
if ( ! empty( $template ) ) {
|
||
$template_base_dir = $plugin_base_dir;
|
||
}
|
||
}
|
||
|
||
$template_base_dir = apply_filters( 'wc_sc_template_base_dir', $template_base_dir, $template_name );
|
||
|
||
return $template_base_dir;
|
||
}
|
||
|
||
/**
|
||
* Check whether credit is sent or not
|
||
*
|
||
* @param string $email_id The email address.
|
||
* @param WC_Coupon $coupon The coupon object.
|
||
* @return boolean
|
||
*/
|
||
public function is_credit_sent( $email_id, $coupon ) {
|
||
|
||
global $smart_coupon_codes;
|
||
|
||
if ( isset( $smart_coupon_codes[ $email_id ] ) && count( $smart_coupon_codes[ $email_id ] ) > 0 ) {
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$coupon_id = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
|
||
} else {
|
||
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
|
||
}
|
||
foreach ( $smart_coupon_codes[ $email_id ] as $generated_coupon_details ) {
|
||
if ( $generated_coupon_details['parent'] === $coupon_id ) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
return false;
|
||
|
||
}
|
||
|
||
/**
|
||
* Generate unique string to be used as coupon code. Also add prefix or suffix if already set
|
||
*
|
||
* @param string $email The email address.
|
||
* @param WC_Coupon $coupon The coupon object.
|
||
* @return string $unique_code
|
||
*/
|
||
public function generate_unique_code( $email = '', $coupon = '' ) {
|
||
$unique_code = '';
|
||
srand( (double) microtime( true ) * 1000000 ); // phpcs:ignore
|
||
|
||
$coupon_code_length = $this->get_coupon_code_length();
|
||
|
||
$chars = array_diff( array_merge( range( 'a', 'z' ), range( '0', '9' ) ), array( 'a', 'e', 'i', 'o', 'u' ) );
|
||
$chars = apply_filters(
|
||
'wc_sc_coupon_code_allowed_characters',
|
||
array_values( $chars ),
|
||
array(
|
||
'source' => $this,
|
||
'email' => $email,
|
||
'coupon_object' => $coupon,
|
||
'coupon_code_length' => $coupon_code_length,
|
||
)
|
||
);
|
||
|
||
$numbers = array_values( array_filter( $chars, 'is_numeric' ) );
|
||
$alphabets = ( count( $chars ) !== count( $numbers ) ) ? array_values( array_diff( $chars, $numbers ) ) : array();
|
||
|
||
if ( empty( $numbers ) || empty( $alphabets ) ) {
|
||
$chars = array_values( array_merge( $alphabets, $numbers ) );
|
||
for ( $rand = 1; $rand <= $coupon_code_length; $rand++ ) {
|
||
$random = rand( 0, count( $chars ) - 1 ); // phpcs:ignore
|
||
$unique_code .= $chars[ $random ];
|
||
}
|
||
} else {
|
||
for ( $rand = 1, $char_count = 0, $num_count = 0; $rand <= $coupon_code_length; $rand++ ) {
|
||
if ( $char_count >= 2 ) {
|
||
$random = rand( 0, count( $numbers ) - 1 ); // phpcs:ignore
|
||
$unique_code .= $numbers[ $random ];
|
||
$char_count = 0;
|
||
$num_count++;
|
||
} elseif ( $num_count >= 1 ) {
|
||
$random = rand( 0, count( $alphabets ) - 1 ); // phpcs:ignore
|
||
$unique_code .= $alphabets[ $random ];
|
||
$num_count = 0;
|
||
$char_count++;
|
||
} else {
|
||
$random = rand( 0, count( $chars ) - 1 ); // phpcs:ignore
|
||
$selected_char = $chars[ $random ];
|
||
$unique_code .= $selected_char;
|
||
if ( is_numeric( $selected_char ) ) {
|
||
$num_count++;
|
||
} else {
|
||
$char_count++;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$coupon_id = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
|
||
} else {
|
||
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
|
||
}
|
||
|
||
if ( $this->is_callable( $coupon, 'get_meta' ) ) {
|
||
if ( 'yes' === $coupon->get_meta( 'auto_generate_coupon' ) ) {
|
||
$prefix = $coupon->get_meta( 'coupon_title_prefix' );
|
||
$suffix = $coupon->get_meta( 'coupon_title_suffix' );
|
||
$unique_code = $prefix . $unique_code . $suffix;
|
||
}
|
||
} else {
|
||
if ( ! empty( $coupon_id ) && get_post_meta( $coupon_id, 'auto_generate_coupon', true ) === 'yes' ) {
|
||
$prefix = get_post_meta( $coupon_id, 'coupon_title_prefix', true );
|
||
$suffix = get_post_meta( $coupon_id, 'coupon_title_suffix', true );
|
||
$unique_code = $prefix . $unique_code . $suffix;
|
||
}
|
||
}
|
||
|
||
return apply_filters(
|
||
'wc_sc_generate_unique_coupon_code',
|
||
$unique_code,
|
||
array(
|
||
'email' => $email,
|
||
'coupon' => $coupon,
|
||
)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Function for generating Gift Certificate
|
||
*
|
||
* @param mixed $email The email address.
|
||
* @param float $amount The amount.
|
||
* @param int $order_id The order id.
|
||
* @param WC_Coupon $coupon The coupon object.
|
||
* @param string $discount_type The discount type.
|
||
* @param array $gift_certificate_receiver_name Receiver name.
|
||
* @param string $message_from_sender Message from sender.
|
||
* @param string $gift_certificate_sender_name Sender name.
|
||
* @param string $gift_certificate_sender_email Sender email.
|
||
* @param string $sending_timestamp timestamp for scheduled sending.
|
||
* @return array of generated coupon details
|
||
*/
|
||
public function generate_smart_coupon( $email, $amount, $order_id = '', $coupon = '', $discount_type = 'smart_coupon', $gift_certificate_receiver_name = '', $message_from_sender = '', $gift_certificate_sender_name = '', $gift_certificate_sender_email = '', $sending_timestamp = '' ) {
|
||
return apply_filters( 'generate_smart_coupon_action', $email, $amount, $order_id, $coupon, $discount_type, $gift_certificate_receiver_name, $message_from_sender, $gift_certificate_sender_name, $gift_certificate_sender_email, $sending_timestamp );
|
||
}
|
||
|
||
/**
|
||
* Function for generating Gift Certificate
|
||
*
|
||
* @param mixed $email The email address.
|
||
* @param float $amount The amount.
|
||
* @param int $order_id The order id.
|
||
* @param WC_Coupon $coupon The coupon object.
|
||
* @param string $discount_type The discount type.
|
||
* @param array $gift_certificate_receiver_name Receiver name.
|
||
* @param string $message_from_sender Message from sender.
|
||
* @param string $gift_certificate_sender_name Sender name.
|
||
* @param string $gift_certificate_sender_email Sender email.
|
||
* @param string $sending_timestamp timestamp for scheduled sending.
|
||
* @return array $smart_coupon_codes associative array containing generated coupon details
|
||
*/
|
||
public function generate_smart_coupon_action( $email, $amount, $order_id = '', $coupon = '', $discount_type = 'smart_coupon', $gift_certificate_receiver_name = '', $message_from_sender = '', $gift_certificate_sender_name = '', $gift_certificate_sender_email = '', $sending_timestamp = '' ) {
|
||
|
||
if ( '' === $email ) {
|
||
return false;
|
||
}
|
||
|
||
global $smart_coupon_codes;
|
||
|
||
$order_id = ( ! empty( $order_id ) ) ? absint( $order_id ) : 0;
|
||
$order = ( function_exists( 'wc_get_order' ) && ! empty( $order_id ) ) ? wc_get_order( $order_id ) : null;
|
||
|
||
$is_callable_order_get_meta = $this->is_callable( $order, 'get_meta' );
|
||
$is_callable_coupon_get_meta = $this->is_callable( $coupon, 'get_meta' );
|
||
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$coupon_id = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
|
||
$is_free_shipping = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_free_shipping' ) ) ) ? ( ( $coupon->get_free_shipping() ) ? 'yes' : 'no' ) : '';
|
||
$discount_type = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
|
||
$expiry_date = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_date_expires' ) ) ) ? $coupon->get_date_expires() : '';
|
||
$coupon_product_ids = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_product_ids' ) ) ) ? $coupon->get_product_ids() : '';
|
||
$coupon_product_categories = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_product_categories' ) ) ) ? $coupon->get_product_categories() : '';
|
||
$coupon_excluded_product_ids = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_excluded_product_ids' ) ) ) ? $coupon->get_excluded_product_ids() : '';
|
||
$coupon_excluded_product_categories = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_excluded_product_categories' ) ) ) ? $coupon->get_excluded_product_categories() : '';
|
||
$coupon_minimum_amount = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_minimum_amount' ) ) ) ? $coupon->get_minimum_amount() : '';
|
||
$coupon_maximum_amount = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_maximum_amount' ) ) ) ? $coupon->get_maximum_amount() : '';
|
||
$coupon_usage_limit = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_usage_limit' ) ) ) ? $coupon->get_usage_limit() : '';
|
||
$coupon_usage_limit_per_user = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_usage_limit_per_user' ) ) ) ? $coupon->get_usage_limit_per_user() : '';
|
||
$coupon_limit_usage_to_x_items = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_limit_usage_to_x_items' ) ) ) ? $coupon->get_limit_usage_to_x_items() : '';
|
||
$is_exclude_sale_items = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_exclude_sale_items' ) ) ) ? ( ( $coupon->get_exclude_sale_items() ) ? 'yes' : 'no' ) : '';
|
||
$is_individual_use = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_individual_use' ) ) ) ? ( ( $coupon->get_individual_use() ) ? 'yes' : 'no' ) : '';
|
||
} else {
|
||
$coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
|
||
$is_free_shipping = ( ! empty( $coupon->free_shipping ) ) ? $coupon->free_shipping : '';
|
||
$discount_type = ( ! empty( $coupon->discount_type ) ) ? $coupon->discount_type : '';
|
||
$expiry_date = ( ! empty( $coupon->expiry_date ) ) ? $coupon->expiry_date : '';
|
||
$coupon_product_ids = ( ! empty( $coupon->product_ids ) ) ? $coupon->product_ids : '';
|
||
$coupon_product_categories = ( ! empty( $coupon->product_categories ) ) ? $coupon->product_categories : '';
|
||
$coupon_excluded_product_ids = ( ! empty( $coupon->exclude_product_ids ) ) ? $coupon->exclude_product_ids : '';
|
||
$coupon_excluded_product_categories = ( ! empty( $coupon->exclude_product_categories ) ) ? $coupon->exclude_product_categories : '';
|
||
$coupon_minimum_amount = ( ! empty( $coupon->minimum_amount ) ) ? $coupon->minimum_amount : '';
|
||
$coupon_maximum_amount = ( ! empty( $coupon->maximum_amount ) ) ? $coupon->maximum_amount : '';
|
||
$coupon_usage_limit = ( ! empty( $coupon->usage_limit ) ) ? $coupon->usage_limit : '';
|
||
$coupon_usage_limit_per_user = ( ! empty( $coupon->usage_limit_per_user ) ) ? $coupon->usage_limit_per_user : '';
|
||
$coupon_limit_usage_to_x_items = ( ! empty( $coupon->limit_usage_to_x_items ) ) ? $coupon->limit_usage_to_x_items : '';
|
||
$is_exclude_sale_items = ( ! empty( $coupon->exclude_sale_items ) ) ? $coupon->exclude_sale_items : '';
|
||
$is_individual_use = ( ! empty( $coupon->individual_use ) ) ? $coupon->individual_use : '';
|
||
}
|
||
|
||
if ( ! is_array( $email ) ) {
|
||
$emails = array( $email => 1 );
|
||
} else {
|
||
$temp_email = ( true === $is_callable_order_get_meta ) ? $order->get_meta( 'temp_gift_card_receivers_emails' ) : get_post_meta( $order_id, 'temp_gift_card_receivers_emails', true );
|
||
if ( ! empty( $temp_email ) && count( $temp_email ) > 0 ) {
|
||
$email = $temp_email;
|
||
}
|
||
$emails = ( ! empty( $coupon_id ) ) ? array_count_values( $email[ $coupon_id ] ) : array();
|
||
}
|
||
|
||
if ( ! empty( $order_id ) ) {
|
||
$receivers_messages = ( true === $is_callable_order_get_meta ) ? $order->get_meta( 'gift_receiver_message' ) : get_post_meta( $order_id, 'gift_receiver_message', true );
|
||
$schedule_gift_sending = ( true === $is_callable_order_get_meta ) ? $order->get_meta( 'wc_sc_schedule_gift_sending' ) : get_post_meta( $order_id, 'wc_sc_schedule_gift_sending', true );
|
||
$sending_timestamps = ( true === $is_callable_order_get_meta ) ? $order->get_meta( 'gift_sending_timestamp' ) : get_post_meta( $order_id, 'gift_sending_timestamp', true );
|
||
}
|
||
|
||
foreach ( $emails as $email_id => $qty ) {
|
||
|
||
if ( $this->is_credit_sent( $email_id, $coupon ) ) {
|
||
continue;
|
||
}
|
||
|
||
$smart_coupon_code = $this->generate_unique_code( $email_id, $coupon );
|
||
|
||
$coupon_post = ( ! empty( $coupon_id ) ) ? get_post( $coupon_id ) : new stdClass();
|
||
|
||
$smart_coupon_args = array(
|
||
'post_title' => strtolower( $smart_coupon_code ),
|
||
'post_excerpt' => ( ! empty( $coupon_post->post_excerpt ) ) ? $coupon_post->post_excerpt : '',
|
||
'post_content' => '',
|
||
'post_status' => 'publish',
|
||
'post_author' => 1,
|
||
'post_type' => 'shop_coupon',
|
||
'post_parent' => ! empty( $coupon_id ) ? absint( $coupon_id ) : 0,
|
||
);
|
||
|
||
$should_schedule = isset( $schedule_gift_sending ) && 'yes' === $schedule_gift_sending && $this->is_valid_timestamp( $sending_timestamp ) ? true : false;
|
||
|
||
if ( $should_schedule ) {
|
||
$smart_coupon_args['post_date_gmt'] = gmdate( 'Y-m-d H:i:s', $sending_timestamp );
|
||
}
|
||
|
||
$smart_coupon = new WC_Coupon();
|
||
$smart_coupon->set_code( $smart_coupon_args['post_title'] );
|
||
$smart_coupon->set_status( $smart_coupon_args['post_status'] );
|
||
$smart_coupon->set_description( $smart_coupon_args['post_excerpt'] );
|
||
|
||
$smart_coupon_id = $smart_coupon->save();
|
||
|
||
if ( ! empty( $smart_coupon_id ) ) {
|
||
$smart_coupon_args = array_diff_key( $smart_coupon_args, array_flip( array( 'post_excerpt', 'post_title', 'post_status', 'post_type' ) ) );
|
||
$smart_coupon_args['ID'] = $smart_coupon_id;
|
||
wp_update_post( $smart_coupon_args );
|
||
}
|
||
|
||
$smart_coupon_id = absint( $smart_coupon_id );
|
||
|
||
$smart_coupon = new WC_Coupon( $smart_coupon_id );
|
||
|
||
$is_callable_smart_coupon_update_meta = $this->is_callable( $smart_coupon, 'update_meta_data' );
|
||
|
||
$type = ( ! empty( $discount_type ) ) ? $discount_type : 'smart_coupon';
|
||
$individual_use = ( ! empty( $is_individual_use ) ) ? $is_individual_use : 'no';
|
||
$minimum_amount = ( ! empty( $coupon_minimum_amount ) ) ? $coupon_minimum_amount : '';
|
||
$maximum_amount = ( ! empty( $coupon_maximum_amount ) ) ? $coupon_maximum_amount : '';
|
||
$product_ids = ( ! empty( $coupon_product_ids ) ) ? implode( ',', $coupon_product_ids ) : '';
|
||
$exclude_product_ids = ( ! empty( $coupon_excluded_product_ids ) ) ? implode( ',', $coupon_excluded_product_ids ) : '';
|
||
$usage_limit = ( ! empty( $coupon_usage_limit ) ) ? $coupon_usage_limit : '';
|
||
$usage_limit_per_user = ( ! empty( $coupon_usage_limit_per_user ) ) ? $coupon_usage_limit_per_user : '';
|
||
$limit_usage_to_x_items = ( ! empty( $coupon_limit_usage_to_x_items ) ) ? $coupon_limit_usage_to_x_items : '';
|
||
$free_shipping = ( ! empty( $is_free_shipping ) ) ? $is_free_shipping : 'no';
|
||
$product_categories = ( ! empty( $coupon_product_categories ) ) ? $coupon_product_categories : array();
|
||
$exclude_product_categories = ( ! empty( $coupon_excluded_product_categories ) ) ? $coupon_excluded_product_categories : array();
|
||
$sc_coupon_validity = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'sc_coupon_validity' ) : ( ( ! empty( $coupon_id ) ) ? get_post_meta( $coupon_id, 'sc_coupon_validity', true ) : '' );
|
||
$is_disable_email_restriction = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'sc_disable_email_restriction' ) : ( ( ! empty( $coupon_id ) ) ? get_post_meta( $coupon_id, 'sc_disable_email_restriction', true ) : '' );
|
||
$sc_restrict_to_new_user = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'sc_restrict_to_new_user' ) : get_post_meta( $coupon_id, 'sc_restrict_to_new_user', true );
|
||
$wc_sc_max_discount = $this->get_post_meta( $coupon_id, 'wc_sc_max_discount', true, true, $order );
|
||
|
||
if ( $this->is_wc_gte_30() && $expiry_date instanceof WC_DateTime ) {
|
||
$expiry_date = ( is_callable( array( $expiry_date, 'getTimestamp' ) ) ) ? $expiry_date->getTimestamp() : null;
|
||
} elseif ( ! is_int( $expiry_date ) ) {
|
||
$expiry_date = strtotime( $expiry_date );
|
||
}
|
||
|
||
if ( ! empty( $coupon_id ) && ! empty( $sc_coupon_validity ) ) {
|
||
$is_parent_coupon_expired = ( ! empty( $expiry_date ) && ( $expiry_date < time() ) ) ? true : false;
|
||
if ( ! $is_parent_coupon_expired ) {
|
||
$validity_suffix = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( 'validity_suffix' ) : get_post_meta( $coupon_id, 'validity_suffix', true );
|
||
// In case of scheduled coupon, expiry date is calculated from scheduled publish date.
|
||
if ( isset( $smart_coupon_args['post_date_gmt'] ) ) {
|
||
$expiry_date = strtotime( $smart_coupon_args['post_date_gmt'] . "+$sc_coupon_validity $validity_suffix" );
|
||
} else {
|
||
$expiry_date = strtotime( "+$sc_coupon_validity $validity_suffix" );
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$expiry_date = $this->get_date_expires_value( $expiry_date );
|
||
if ( true === $is_callable_smart_coupon_update_meta ) {
|
||
$smart_coupon->set_date_expires( $expiry_date );
|
||
} else {
|
||
update_post_meta( $smart_coupon_id, 'date_expires', $expiry_date );
|
||
}
|
||
} else {
|
||
$expiry_date = ( ! empty( $expiry_date ) ) ? gmdate( 'Y-m-d', intval( $expiry_date ) + $this->wc_timezone_offset() ) : '';
|
||
if ( true === $is_callable_smart_coupon_update_meta ) {
|
||
$smart_coupon->update_meta_data( 'expiry_date', $expiry_date );
|
||
} else {
|
||
update_post_meta( $smart_coupon_id, 'expiry_date', $expiry_date );
|
||
}
|
||
}
|
||
|
||
if ( 'smart_coupon' === $type ) {
|
||
$this->update_post_meta( $smart_coupon_id, 'wc_sc_original_amount', $amount, false, $order );
|
||
}
|
||
|
||
if ( true === $is_callable_smart_coupon_update_meta ) {
|
||
$smart_coupon->set_amount( $amount );
|
||
$smart_coupon->set_excluded_product_ids( $exclude_product_ids );
|
||
$smart_coupon->set_excluded_product_categories( $exclude_product_categories );
|
||
$smart_coupon->set_discount_type( $type );
|
||
$smart_coupon->set_individual_use( $this->wc_string_to_bool( $individual_use ) );
|
||
$smart_coupon->set_minimum_amount( $minimum_amount );
|
||
$smart_coupon->set_maximum_amount( $maximum_amount );
|
||
$smart_coupon->set_product_ids( $product_ids );
|
||
$smart_coupon->set_usage_limit( $usage_limit );
|
||
$smart_coupon->set_usage_limit_per_user( $usage_limit_per_user );
|
||
$smart_coupon->set_limit_usage_to_x_items( $limit_usage_to_x_items );
|
||
$smart_coupon->set_free_shipping( $this->wc_string_to_bool( $free_shipping ) );
|
||
$smart_coupon->set_product_categories( $product_categories );
|
||
$smart_coupon->set_exclude_sale_items( $this->wc_string_to_bool( $is_exclude_sale_items ) );
|
||
$smart_coupon->update_meta_data( 'sc_restrict_to_new_user', $sc_restrict_to_new_user );
|
||
if ( ! empty( $order_id ) ) {
|
||
$smart_coupon->update_meta_data( 'generated_from_order_id', $order_id );
|
||
}
|
||
if ( empty( $is_disable_email_restriction ) || 'no' === $is_disable_email_restriction ) {
|
||
// Update customer_email now if coupon is not scheduled otherwise it would be updated by action scheduler later on.
|
||
if ( ! $should_schedule ) {
|
||
$smart_coupon->set_email_restrictions( array( $email_id ) );
|
||
}
|
||
}
|
||
} else {
|
||
update_post_meta( $smart_coupon_id, 'discount_type', $type );
|
||
update_post_meta( $smart_coupon_id, 'coupon_amount', $amount );
|
||
update_post_meta( $smart_coupon_id, 'individual_use', $individual_use );
|
||
update_post_meta( $smart_coupon_id, 'minimum_amount', $minimum_amount );
|
||
update_post_meta( $smart_coupon_id, 'maximum_amount', $maximum_amount );
|
||
update_post_meta( $smart_coupon_id, 'product_ids', $product_ids );
|
||
update_post_meta( $smart_coupon_id, 'exclude_product_ids', $exclude_product_ids );
|
||
update_post_meta( $smart_coupon_id, 'usage_limit', $usage_limit );
|
||
update_post_meta( $smart_coupon_id, 'usage_limit_per_user', $usage_limit_per_user );
|
||
update_post_meta( $smart_coupon_id, 'limit_usage_to_x_items', $limit_usage_to_x_items );
|
||
update_post_meta( $smart_coupon_id, 'free_shipping', $free_shipping );
|
||
update_post_meta( $smart_coupon_id, 'product_categories', $product_categories );
|
||
update_post_meta( $smart_coupon_id, 'exclude_product_categories', $exclude_product_categories );
|
||
update_post_meta( $smart_coupon_id, 'exclude_sale_items', $is_exclude_sale_items );
|
||
update_post_meta( $smart_coupon_id, 'sc_restrict_to_new_user', $sc_restrict_to_new_user );
|
||
if ( ! empty( $order_id ) ) {
|
||
update_post_meta( $smart_coupon_id, 'generated_from_order_id', $order_id );
|
||
}
|
||
if ( empty( $is_disable_email_restriction ) || 'no' === $is_disable_email_restriction ) {
|
||
// Update customer_email now if coupon is not scheduled otherwise it would be updated by action scheduler later on.
|
||
if ( ! $should_schedule ) {
|
||
update_post_meta( $smart_coupon_id, 'customer_email', array( $email_id ) );
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( ! $this->is_wc_gte_30() ) {
|
||
$apply_before_tax = ( ! empty( $coupon->apply_before_tax ) ) ? $coupon->apply_before_tax : 'no';
|
||
if ( true === $is_callable_smart_coupon_update_meta ) {
|
||
$smart_coupon->update_meta_data( 'apply_before_tax', $apply_before_tax );
|
||
} else {
|
||
update_post_meta( $smart_coupon_id, 'apply_before_tax', $apply_before_tax );
|
||
}
|
||
}
|
||
|
||
// Add terms to auto-generated if found in parent coupon.
|
||
$coupon_terms = get_the_terms( $coupon_id, 'sc_coupon_category' );
|
||
if ( ! empty( $coupon_terms ) ) {
|
||
$term_ids = array_column( $coupon_terms, 'term_id' );
|
||
wp_set_object_terms( $smart_coupon_id, $term_ids, 'sc_coupon_category', false );
|
||
}
|
||
|
||
if ( ! empty( $wc_sc_max_discount ) ) {
|
||
$this->update_post_meta( $smart_coupon_id, 'wc_sc_max_discount', $wc_sc_max_discount, true, $order );
|
||
}
|
||
|
||
if ( $this->is_wc_gte_32() ) {
|
||
$wc_sc_expiry_time = ( true === $is_callable_coupon_get_meta ) ? (int) $coupon->get_meta( 'wc_sc_expiry_time' ) : (int) get_post_meta( $coupon_id, 'wc_sc_expiry_time', true );
|
||
if ( ! empty( $wc_sc_expiry_time ) ) {
|
||
if ( true === $is_callable_smart_coupon_update_meta ) {
|
||
$smart_coupon->update_meta_data( 'wc_sc_expiry_time', $wc_sc_expiry_time );
|
||
} else {
|
||
update_post_meta( $smart_coupon_id, 'wc_sc_expiry_time', $wc_sc_expiry_time );
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( $this->is_callable( $smart_coupon, 'save' ) ) {
|
||
$smart_coupon->save();
|
||
}
|
||
|
||
/**
|
||
* Hook for 3rd party developers to add data in generated coupon
|
||
*
|
||
* New coupon id new_coupon_id Newly generated coupon post id
|
||
* Reference coupon ref_coupon This is the coupon from which meta will be copied to newly created coupon
|
||
*/
|
||
do_action(
|
||
'wc_sc_new_coupon_generated',
|
||
array(
|
||
'new_coupon_id' => $smart_coupon_id,
|
||
'ref_coupon' => $coupon,
|
||
)
|
||
);
|
||
|
||
$generated_coupon_details = array(
|
||
'parent' => ( ! empty( $coupon_id ) ) ? $coupon_id : 0,
|
||
'code' => $smart_coupon_code,
|
||
'amount' => $amount,
|
||
);
|
||
|
||
$smart_coupon_codes[ $email_id ][] = $generated_coupon_details;
|
||
|
||
if ( ! empty( $order_id ) ) {
|
||
$is_gift = ( true === $is_callable_order_get_meta ) ? $order->get_meta( 'is_gift' ) : get_post_meta( $order_id, 'is_gift', true );
|
||
} else {
|
||
$is_gift = 'no';
|
||
}
|
||
|
||
if ( is_array( $email ) && ! empty( $coupon_id ) && isset( $email[ $coupon_id ] ) ) {
|
||
$message_index = array_search( $email_id, $email[ $coupon_id ], true );
|
||
if ( false !== $message_index && isset( $receivers_messages[ $coupon_id ][ $message_index ] ) && ! empty( $receivers_messages[ $coupon_id ][ $message_index ] ) ) {
|
||
$message_from_sender = $receivers_messages[ $coupon_id ][ $message_index ];
|
||
unset( $email[ $coupon_id ][ $message_index ] );
|
||
$this->update_post_meta( $order_id, 'temp_gift_card_receivers_emails', $email, false, $order );
|
||
}
|
||
}
|
||
|
||
if ( ( isset( $schedule_gift_sending ) && 'yes' === $schedule_gift_sending && $this->is_valid_timestamp( $sending_timestamp ) ) ) {
|
||
$wc_sc_coupon_receiver_details = array(
|
||
'coupon_details' => $generated_coupon_details,
|
||
'gift_certificate_receiver_email' => $email_id,
|
||
'gift_certificate_receiver_name' => $gift_certificate_receiver_name,
|
||
'message_from_sender' => $message_from_sender,
|
||
'gift_certificate_sender_name' => $gift_certificate_sender_name,
|
||
'gift_certificate_sender_email' => $gift_certificate_sender_email,
|
||
);
|
||
if ( true === $is_callable_smart_coupon_update_meta ) {
|
||
$smart_coupon->update_meta_data( 'wc_sc_coupon_receiver_details', $wc_sc_coupon_receiver_details );
|
||
} else {
|
||
update_post_meta( $smart_coupon_id, 'wc_sc_coupon_receiver_details', $wc_sc_coupon_receiver_details );
|
||
}
|
||
} else {
|
||
$is_send_email = $this->is_email_template_enabled();
|
||
$combine_emails = $this->is_email_template_enabled( 'combine' );
|
||
if ( 'yes' === $is_send_email ) {
|
||
if ( 'yes' === $combine_emails ) {
|
||
$coupon_receiver_details = ( true === $is_callable_order_get_meta ) ? $order->get_meta( 'sc_coupon_receiver_details' ) : get_post_meta( $order_id, 'sc_coupon_receiver_details', true );
|
||
if ( empty( $coupon_receiver_details ) || ! is_array( $coupon_receiver_details ) ) {
|
||
$coupon_receiver_details = array();
|
||
}
|
||
$coupon_receiver_details[] = array(
|
||
'code' => $generated_coupon_details['code'],
|
||
'amount' => $amount,
|
||
'email' => $email_id,
|
||
'message' => $message_from_sender,
|
||
);
|
||
$this->update_post_meta( $order_id, 'sc_coupon_receiver_details', $coupon_receiver_details, false, $order );
|
||
} else {
|
||
$this->sa_email_coupon( array( $email_id => $generated_coupon_details ), $type, $order_id, $gift_certificate_receiver_name, $message_from_sender, $gift_certificate_sender_name, $gift_certificate_sender_email, $is_gift );
|
||
}
|
||
} else {
|
||
if ( ! empty( $order_id ) ) {
|
||
$coupon_receiver_details = ( true === $is_callable_order_get_meta ) ? $order->get_meta( 'sc_coupon_receiver_details' ) : get_post_meta( $order_id, 'sc_coupon_receiver_details', true );
|
||
if ( empty( $coupon_receiver_details ) || ! is_array( $coupon_receiver_details ) ) {
|
||
$coupon_receiver_details = array();
|
||
}
|
||
$coupon_receiver_details[] = array(
|
||
'code' => $generated_coupon_details['code'],
|
||
'amount' => $amount,
|
||
'email' => $email_id,
|
||
'message' => $message_from_sender,
|
||
);
|
||
$this->update_post_meta( $order_id, 'sc_coupon_receiver_details', $coupon_receiver_details, false, $order );
|
||
}
|
||
}
|
||
}
|
||
if ( $this->is_callable( $smart_coupon, 'save' ) ) {
|
||
$smart_coupon->save();
|
||
}
|
||
}
|
||
|
||
return $smart_coupon_codes;
|
||
|
||
}
|
||
|
||
/**
|
||
* Function to set that Smart Coupons plugin is used to auto generate a coupon
|
||
*
|
||
* @param array $args Data.
|
||
*/
|
||
public function smart_coupons_plugin_used( $args = array() ) {
|
||
|
||
$is_show_review_notice = get_option( 'wc_sc_is_show_review_notice' );
|
||
|
||
if ( false === $is_show_review_notice ) {
|
||
update_option( 'wc_sc_is_show_review_notice', time(), 'no' );
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Add button to export coupons on Coupons admin page
|
||
*/
|
||
public function woocommerce_restrict_manage_smart_coupons() {
|
||
global $typenow, $wp_query, $wp, $woocommerce_smart_coupon;
|
||
|
||
if ( 'shop_coupon' !== $typenow ) {
|
||
return;
|
||
}
|
||
|
||
$is_print = get_option( 'smart_coupons_is_print_coupon', 'yes' );
|
||
$is_print = apply_filters( 'wc_sc_admin_show_print_button', wc_string_to_bool( $is_print ), array( 'source' => $woocommerce_smart_coupon ) );
|
||
$print_url = add_query_arg(
|
||
array(
|
||
'print-coupons' => 'yes',
|
||
'source' => 'wc-smart-coupons',
|
||
'coupon-codes' => '',
|
||
),
|
||
home_url()
|
||
);
|
||
wc_product_dropdown_categories(
|
||
array(
|
||
'selected' => isset( $wp_query->query_vars['sc_coupon_category'] ) ? $wp_query->query_vars['sc_coupon_category'] : '',
|
||
'taxonomy' => 'sc_coupon_category',
|
||
'name' => 'sc_coupon_category',
|
||
'option_select_text' => __( 'Filter by category', 'woocommerce-smart-coupons' ),
|
||
'hide_empty' => 0,
|
||
)
|
||
);
|
||
|
||
?>
|
||
<script type="text/javascript">
|
||
jQuery(function(){
|
||
<?php if ( true === $is_print ) { ?>
|
||
jQuery('body').on('click', 'a#wc_sc_print_coupons', function( e ){
|
||
let selected = jQuery('input[id^=cb-select-]').map(function(){
|
||
if ( jQuery(this).is(':checked') ) {
|
||
return jQuery(this).closest('tr').find('.coupon_code .row-title').text();
|
||
}
|
||
}).get();
|
||
if ( selected && selected.length > 0 ) {
|
||
let url = decodeURIComponent( '<?php echo rawurlencode( (string) $print_url ); ?>' );
|
||
url += '=' + selected.join(',');
|
||
window.open( url, '_blank' );
|
||
} else {
|
||
let sc_print_notice = decodeURIComponent( '<?php echo rawurlencode( (string) __( 'Please select at least one coupon to print.', 'woocommerce-smart-coupons' ) ); ?>' );
|
||
alert( sc_print_notice );
|
||
}
|
||
});
|
||
<?php } ?>
|
||
});
|
||
</script>
|
||
<div class="alignright" style="margin-top: 1px;" >
|
||
<?php
|
||
if ( ! empty( $_SERVER['QUERY_STRING'] ) ) {
|
||
echo '<input type="hidden" name="sc_export_query_args" value="' . esc_attr( wc_clean( wp_unslash( $_SERVER['QUERY_STRING'] ) ) ) . '">'; // phpcs:ignore
|
||
}
|
||
?>
|
||
<button type="submit" class="button" id="export_coupons" name="export_coupons" value="<?php echo esc_attr__( 'Export', 'woocommerce-smart-coupons' ); ?>"><span class="dashicons dashicons-upload"></span><?php echo esc_html__( 'Export', 'woocommerce-smart-coupons' ); ?></button>
|
||
<?php if ( true === $is_print ) { ?>
|
||
<a class="button" id="wc_sc_print_coupons" href="javascript:void(0)" title="<?php echo esc_attr__( 'Print selected coupons', 'woocommerce-smart-coupons' ); ?>"><span class="dashicons dashicons-media-default"></span><?php echo esc_html__( 'Print', 'woocommerce-smart-coupons' ); ?></a>
|
||
<?php } ?>
|
||
<a class="button" id="sc-manage-category" title="" href="<?php echo esc_url( admin_url( 'edit-tags.php?taxonomy=sc_coupon_category&post_type=shop_coupon' ) ); ?>"><span class="dashicons dashicons-admin-tools"></span><?php echo esc_attr__( 'Manage coupon categories', 'woocommerce-smart-coupons' ); ?></a>
|
||
</div>
|
||
<?php
|
||
}
|
||
|
||
/**
|
||
* Export coupons
|
||
*/
|
||
public function woocommerce_export_coupons() {
|
||
global $typenow, $wp_query, $wp, $post;
|
||
|
||
if ( is_admin() && isset( $_GET['export_coupons'] ) && current_user_can( 'manage_woocommerce' ) ) { // phpcs:ignore
|
||
|
||
$args = array(
|
||
'post_status' => '',
|
||
'post_type' => '',
|
||
'm' => '',
|
||
'posts_per_page' => -1,
|
||
'fields' => 'ids',
|
||
);
|
||
|
||
if ( ! empty( $_REQUEST['sc_export_query_args'] ) ) { // phpcs:ignore
|
||
parse_str( wc_clean( wp_unslash( $_REQUEST['sc_export_query_args'] ) ), $sc_args ); // phpcs:ignore
|
||
}
|
||
$args = array_merge( $args, $sc_args );
|
||
|
||
$get_coupon_type = ( ! empty( $_GET['coupon_type'] ) ) ? wc_clean( wp_unslash( $_GET['coupon_type'] ) ) : ''; // phpcs:ignore
|
||
$get_post = ( ! empty( $_GET['post'] ) ) ? wc_clean( wp_unslash( $_GET['post'] ) ) : ''; // phpcs:ignore
|
||
|
||
if ( isset( $get_coupon_type ) && '' !== $get_coupon_type ) {
|
||
$args['meta_query'] = array( // phpcs:ignore
|
||
array(
|
||
'key' => 'discount_type',
|
||
'value' => $get_coupon_type,
|
||
),
|
||
);
|
||
}
|
||
|
||
if ( ! empty( $get_post ) ) {
|
||
$args['post__in'] = $get_post;
|
||
}
|
||
|
||
foreach ( $args as $key => $value ) {
|
||
if ( array_key_exists( $key, wc_clean( wp_unslash( $_GET ) ) ) ) { // phpcs:ignore
|
||
$args[ $key ] = wc_clean( wp_unslash( $_GET[ $key ] ) ); // phpcs:ignore
|
||
}
|
||
}
|
||
|
||
if ( 'all' === $args['post_status'] ) {
|
||
$args['post_status'] = array( 'publish', 'draft', 'pending', 'private', 'future' );
|
||
|
||
}
|
||
|
||
$query = new WP_Query( $args );
|
||
|
||
$post_ids = $query->posts;
|
||
|
||
$this->export_coupon( '', wc_clean( wp_unslash( $_GET ) ), $post_ids ); // phpcs:ignore
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Generate coupon code
|
||
*
|
||
* @param array $post POST.
|
||
* @param array $get GET.
|
||
* @param array $post_ids Post ids.
|
||
* @param array $coupon_postmeta_headers Coupon postmeta headers.
|
||
* @return array $data associative array of generated coupon
|
||
*/
|
||
public function generate_coupons_code( $post = array(), $get = array(), $post_ids = array(), $coupon_postmeta_headers = array() ) {
|
||
global $wpdb, $wp, $wp_query;
|
||
|
||
if ( ! empty( $post_ids ) ) {
|
||
if ( ! is_array( $post_ids ) ) {
|
||
$post_ids = array( $post_ids );
|
||
}
|
||
$post_ids = array_map( 'absint', $post_ids );
|
||
}
|
||
|
||
$data = array();
|
||
if ( ! empty( $post ) && isset( $post['generate_and_import'] ) ) {
|
||
|
||
$customer_emails = array();
|
||
$unique_code = '';
|
||
if ( ! empty( $post['customer_email'] ) ) {
|
||
$emails = explode( ',', $post['customer_email'] );
|
||
if ( is_array( $emails ) && count( $emails ) > 0 ) {
|
||
for ( $j = 1; $j <= $post['no_of_coupons_to_generate']; $j++ ) {
|
||
$email = ( ! empty( $emails[ $j - 1 ] ) ) ? sanitize_email( $emails[ $j - 1 ] ) : '';
|
||
$customer_emails[ $j ] = ( ! empty( $email ) && is_email( $email ) ) ? $email : '';
|
||
}
|
||
}
|
||
}
|
||
|
||
$all_discount_types = wc_get_coupon_types();
|
||
$generated_codes = array();
|
||
|
||
for ( $i = 1; $i <= $post['no_of_coupons_to_generate']; $i++ ) {
|
||
$customer_email = ( ! empty( $customer_emails[ $i ] ) ) ? $customer_emails[ $i ] : '';
|
||
$unique_code = $this->generate_unique_code( $customer_email );
|
||
if ( ! empty( $generated_codes ) && in_array( $unique_code, $generated_codes, true ) ) {
|
||
$max = ( $post['no_of_coupons_to_generate'] * 10 ) - 1;
|
||
do {
|
||
$unique_code_temp = $unique_code . wp_rand( 0, $max );
|
||
} while ( in_array( $unique_code_temp, $generated_codes, true ) );
|
||
$unique_code = $unique_code_temp;
|
||
}
|
||
$generated_codes[] = $unique_code;
|
||
$post['coupon_title_prefix'] = ( ! empty( $post['coupon_title_prefix'] ) ) ? $post['coupon_title_prefix'] : '';
|
||
$post['coupon_title_suffix'] = ( ! empty( $post['coupon_title_suffix'] ) ) ? $post['coupon_title_suffix'] : '';
|
||
$code = $post['coupon_title_prefix'] . $unique_code . $post['coupon_title_suffix'];
|
||
|
||
$data[ $i ]['post_title'] = strtolower( $code );
|
||
|
||
$discount_type = ( ! empty( $post['discount_type'] ) ) ? $post['discount_type'] : 'percent';
|
||
|
||
if ( ! empty( $all_discount_types[ $discount_type ] ) ) {
|
||
$data[ $i ]['discount_type'] = $all_discount_types[ $discount_type ];
|
||
} else {
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$data[ $i ]['discount_type'] = 'Percentage discount';
|
||
} else {
|
||
$data[ $i ]['discount_type'] = 'Cart % Discount';
|
||
}
|
||
}
|
||
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$post['product_ids'] = ( ! empty( $post['product_ids'] ) ) ? ( ( is_array( $post['product_ids'] ) ) ? implode( ',', $post['product_ids'] ) : $post['product_ids'] ) : '';
|
||
$post['exclude_product_ids'] = ( ! empty( $post['exclude_product_ids'] ) ) ? ( ( is_array( $post['exclude_product_ids'] ) ) ? implode( ',', $post['exclude_product_ids'] ) : $post['exclude_product_ids'] ) : '';
|
||
}
|
||
|
||
$data[ $i ]['coupon_amount'] = $post['coupon_amount'];
|
||
$data[ $i ]['individual_use'] = ( isset( $post['individual_use'] ) ) ? 'yes' : 'no';
|
||
$data[ $i ]['product_ids'] = ( isset( $post['product_ids'] ) ) ? str_replace( array( ',', ' ' ), array( '|', '' ), $post['product_ids'] ) : '';
|
||
$data[ $i ]['exclude_product_ids'] = ( isset( $post['exclude_product_ids'] ) ) ? str_replace( array( ',', ' ' ), array( '|', '' ), $post['exclude_product_ids'] ) : '';
|
||
$data[ $i ]['usage_limit'] = ( isset( $post['usage_limit'] ) ) ? $post['usage_limit'] : '';
|
||
$data[ $i ]['usage_limit_per_user'] = ( isset( $post['usage_limit_per_user'] ) ) ? $post['usage_limit_per_user'] : '';
|
||
$data[ $i ]['limit_usage_to_x_items'] = ( isset( $post['limit_usage_to_x_items'] ) ) ? $post['limit_usage_to_x_items'] : '';
|
||
if ( empty( $post['expiry_date'] ) && ! empty( $post['sc_coupon_validity'] ) && ! empty( $post['validity_suffix'] ) ) {
|
||
$data[ $i ]['expiry_date'] = gmdate( 'Y-m-d', strtotime( '+' . $post['sc_coupon_validity'] . ' ' . $post['validity_suffix'] ) + $this->wc_timezone_offset() );
|
||
} else {
|
||
$data[ $i ]['expiry_date'] = $post['expiry_date'];
|
||
}
|
||
$data[ $i ]['free_shipping'] = ( isset( $post['free_shipping'] ) ) ? 'yes' : 'no';
|
||
$data[ $i ]['product_categories'] = ( isset( $post['product_categories'] ) ) ? implode( '|', $post['product_categories'] ) : '';
|
||
$data[ $i ]['exclude_product_categories'] = ( isset( $post['exclude_product_categories'] ) ) ? implode( '|', $post['exclude_product_categories'] ) : '';
|
||
$data[ $i ]['exclude_sale_items'] = ( isset( $post['exclude_sale_items'] ) ) ? 'yes' : 'no';
|
||
$data[ $i ]['minimum_amount'] = ( isset( $post['minimum_amount'] ) ) ? $post['minimum_amount'] : '';
|
||
$data[ $i ]['maximum_amount'] = ( isset( $post['maximum_amount'] ) ) ? $post['maximum_amount'] : '';
|
||
$data[ $i ]['customer_email'] = ( ! empty( $customer_emails ) ) ? $customer_emails[ $i ] : '';
|
||
$data[ $i ]['sc_coupon_validity'] = ( isset( $post['sc_coupon_validity'] ) ) ? $post['sc_coupon_validity'] : '';
|
||
$data[ $i ]['validity_suffix'] = ( isset( $post['validity_suffix'] ) ) ? $post['validity_suffix'] : '';
|
||
$data[ $i ]['is_pick_price_of_product'] = ( isset( $post['is_pick_price_of_product'] ) ) ? 'yes' : 'no';
|
||
$data[ $i ]['sc_disable_email_restriction'] = ( isset( $post['sc_disable_email_restriction'] ) ) ? 'yes' : 'no';
|
||
$data[ $i ]['sc_is_visible_storewide'] = ( isset( $post['sc_is_visible_storewide'] ) ) ? 'yes' : 'no';
|
||
$data[ $i ]['coupon_title_prefix'] = ( isset( $post['coupon_title_prefix'] ) ) ? $post['coupon_title_prefix'] : '';
|
||
$data[ $i ]['coupon_title_suffix'] = ( isset( $post['coupon_title_suffix'] ) ) ? $post['coupon_title_suffix'] : '';
|
||
$data[ $i ]['sc_restrict_to_new_user'] = ( isset( $post['sc_restrict_to_new_user'] ) ) ? $post['sc_restrict_to_new_user'] : '';
|
||
$data[ $i ]['post_status'] = 'publish';
|
||
$data[ $i ]['post_excerpt'] = ( isset( $post['excerpt'] ) ) ? $post['excerpt'] : '';
|
||
$data[ $i ]['wc_sc_max_discount'] = ( isset( $post['wc_sc_max_discount'] ) ) ? $post['wc_sc_max_discount'] : '';
|
||
$data[ $i ]['wc_sc_expiry_time'] = ( isset( $post['wc_sc_expiry_time'] ) ) ? $post['wc_sc_expiry_time'] : '';
|
||
$data[ $i ]['wc_sc_product_attribute_ids'] = ( isset( $post['wc_sc_product_attribute_ids'] ) ) ? implode( '|', $post['wc_sc_product_attribute_ids'] ) : '';
|
||
$data[ $i ]['wc_sc_exclude_product_attribute_ids'] = ( isset( $post['wc_sc_exclude_product_attribute_ids'] ) ) ? implode( '|', $post['wc_sc_exclude_product_attribute_ids'] ) : '';
|
||
$data[ $i ]['sc_coupon_category'] = ( isset( $post['tax_input']['sc_coupon_category'] ) ) ? implode( '|', $post['tax_input']['sc_coupon_category'] ) : '';
|
||
|
||
$data[ $i ] = apply_filters( 'sc_generate_coupon_meta', $data[ $i ], $post );
|
||
|
||
}
|
||
}
|
||
|
||
if ( ! empty( $get ) && isset( $get['export_coupons'] ) ) {
|
||
|
||
$headers = array_keys( $coupon_postmeta_headers );
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$headers[] = 'date_expires';
|
||
}
|
||
$headers = esc_sql( $headers );
|
||
$how_many_headers = count( $headers );
|
||
$header_placeholder = array_fill( 0, $how_many_headers, '%s' );
|
||
|
||
$how_many_ids = count( $post_ids );
|
||
$id_placeholder = array_fill( 0, $how_many_ids, '%d' );
|
||
|
||
$wpdb->query( $wpdb->prepare( 'SET SESSION group_concat_max_len=%d', 999999 ) ); // phpcs:ignore
|
||
|
||
$unique_post_ids = array_unique( $post_ids );
|
||
|
||
$results = wp_cache_get( 'wc_sc_exported_coupon_data_' . implode( '_', $unique_post_ids ), 'woocommerce_smart_coupons' );
|
||
|
||
if ( false === $results ) {
|
||
$results = $wpdb->get_results( // phpcs:ignore
|
||
// phpcs:disable
|
||
$wpdb->prepare(
|
||
"SELECT p.ID,
|
||
p.post_title,
|
||
p.post_excerpt,
|
||
p.post_status,
|
||
p.post_parent,
|
||
p.menu_order,
|
||
DATE_FORMAT(p.post_date,'%%d-%%m-%%Y %%H:%%i:%%s') AS post_date,
|
||
GROUP_CONCAT(pm.meta_key order by pm.meta_id SEPARATOR '###') AS coupon_meta_key,
|
||
GROUP_CONCAT(pm.meta_value order by pm.meta_id SEPARATOR '###') AS coupon_meta_value
|
||
FROM {$wpdb->prefix}posts as p JOIN {$wpdb->prefix}postmeta as pm ON (p.ID = pm.post_id
|
||
AND pm.meta_key IN (" . implode( ',', $header_placeholder ) . ') )
|
||
WHERE p.ID IN (' . implode( ',', $id_placeholder ) . ') AND pm.meta_value IS NOT NULL
|
||
GROUP BY p.id ORDER BY p.id',
|
||
array_merge( $headers, $post_ids )
|
||
),
|
||
// phpcs:enable
|
||
ARRAY_A
|
||
);
|
||
wp_cache_set( 'wc_sc_exported_coupon_data_' . implode( '_', $unique_post_ids ), $results, 'woocommerce_smart_coupons' );
|
||
$this->maybe_add_cache_key( 'wc_sc_exported_coupon_data_' . implode( '_', $unique_post_ids ) );
|
||
}
|
||
|
||
foreach ( $results as $result ) {
|
||
|
||
$coupon_meta_key = explode( '###', $result['coupon_meta_key'] );
|
||
$coupon_meta_value = explode( '###', $result['coupon_meta_value'] );
|
||
|
||
unset( $result['coupon_meta_key'] );
|
||
unset( $result['coupon_meta_value'] );
|
||
|
||
if ( ! empty( $result['post_date'] ) ) {
|
||
$timestamp = strtotime( $result['post_date'] ) + 1;
|
||
$result['post_date'] = gmdate( 'd-m-Y H:i:s', $timestamp );
|
||
}
|
||
|
||
$id = $result['ID'];
|
||
$data[ $id ] = $result;
|
||
|
||
foreach ( $coupon_meta_key as $index => $key ) {
|
||
if ( 'product_ids' === $key || 'exclude_product_ids' === $key ) {
|
||
$data[ $id ][ $key ] = ( isset( $coupon_meta_value[ $index ] ) ) ? str_replace( array( ',', ' ' ), array( '|', '' ), $coupon_meta_value[ $index ] ) : '';
|
||
} elseif ( 'product_categories' === $key || 'exclude_product_categories' === $key ) {
|
||
$data[ $id ][ $key ] = ( ! empty( $coupon_meta_value[ $index ] ) ) ? implode( '|', maybe_unserialize( stripslashes( $coupon_meta_value[ $index ] ) ) ) : '';
|
||
} elseif ( '_used_by' === $key ) {
|
||
if ( ! isset( $data[ $id ][ $key ] ) ) {
|
||
$data[ $id ][ $key ] = '';
|
||
}
|
||
$data[ $id ][ $key ] .= '|' . $coupon_meta_value[ $index ];
|
||
$data[ $id ][ $key ] = trim( $data[ $id ][ $key ], '|' );
|
||
} elseif ( 'date_expires' === $key && $this->is_wc_gte_30() ) {
|
||
if ( ! empty( $coupon_meta_value[ $index ] ) ) {
|
||
$data[ $id ]['expiry_date'] = gmdate( 'Y-m-d', intval( $coupon_meta_value[ $index ] ) + $this->wc_timezone_offset() );
|
||
}
|
||
} elseif ( 'ID' !== $key ) {
|
||
if ( ! empty( $coupon_meta_value[ $index ] ) ) {
|
||
if ( is_serialized( $coupon_meta_value[ $index ] ) ) {
|
||
$temp_data = maybe_unserialize( stripslashes( $coupon_meta_value[ $index ] ) );
|
||
$current_temp_data = current( $temp_data );
|
||
if ( ! is_array( $current_temp_data ) ) {
|
||
$temp_data = implode( ',', $temp_data );
|
||
} else {
|
||
$temp_data = apply_filters(
|
||
'wc_sc_export_coupon_meta_data',
|
||
$temp_data,
|
||
array(
|
||
'coupon_id' => $id,
|
||
'index' => $index,
|
||
'meta_key' => $key, // phpcs:ignore
|
||
'meta_keys' => $coupon_meta_key,
|
||
'meta_values' => $coupon_meta_value,
|
||
)
|
||
);
|
||
}
|
||
} else {
|
||
$temp_data = $coupon_meta_value[ $index ];
|
||
}
|
||
$data[ $id ][ $key ] = apply_filters(
|
||
'wc_sc_export_coupon_meta',
|
||
$temp_data,
|
||
array(
|
||
'coupon_id' => $id,
|
||
'index' => $index,
|
||
'meta_key' => $key, // phpcs:ignore
|
||
'meta_value' => $coupon_meta_value[ $index ], // phpcs:ignore
|
||
'meta_keys' => $coupon_meta_key,
|
||
'meta_values' => $coupon_meta_value,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return $data;
|
||
|
||
}
|
||
|
||
/**
|
||
* Export coupon CSV data
|
||
*
|
||
* @param array $columns_header Column header.
|
||
* @param array $data The data.
|
||
* @return array $file_data
|
||
*/
|
||
public function export_coupon_csv( $columns_header, $data ) {
|
||
|
||
$getfield = '';
|
||
|
||
foreach ( $columns_header as $key => $value ) {
|
||
$getfield .= $key . ',';
|
||
}
|
||
|
||
$fields = substr_replace( $getfield, '', -1 );
|
||
|
||
$csv_file_name = get_bloginfo( 'name' ) . gmdate( 'd-M-Y_H_i_s' ) . '.csv';
|
||
|
||
$fields .= $this->get_coupon_csv_data( $columns_header, $data );
|
||
|
||
$upload_dir = wp_get_upload_dir();
|
||
|
||
$file_data = array();
|
||
$file_data['wp_upload_dir'] = $upload_dir['basedir'] . '/woocommerce_uploads/';
|
||
$file_data['file_name'] = $csv_file_name;
|
||
$file_data['file_content'] = $fields;
|
||
|
||
if ( isset( $upload_dir['error'] ) && ! empty( $upload_dir['error'] ) ) {
|
||
$file_data['error'] = $upload_dir['error'];
|
||
}
|
||
|
||
return $file_data;
|
||
}
|
||
|
||
/**
|
||
* Export coupon CSV data
|
||
*
|
||
* @param array $columns_header Column header.
|
||
* @param array $data The data.
|
||
* @return array $file_data
|
||
*/
|
||
public function get_coupon_csv_data( $columns_header, $data ) {
|
||
|
||
$each_field = array_keys( $columns_header );
|
||
|
||
$csv_data = '';
|
||
|
||
foreach ( (array) $data as $row ) {
|
||
$count_columns_header = count( $columns_header );
|
||
for ( $i = 0; $i < $count_columns_header; $i++ ) {
|
||
if ( 0 === $i ) {
|
||
$csv_data .= "\n";
|
||
}
|
||
|
||
if ( array_key_exists( $each_field[ $i ], $row ) ) {
|
||
$row_each_field = $row[ $each_field[ $i ] ];
|
||
} else {
|
||
$row_each_field = '';
|
||
}
|
||
|
||
$array = str_replace( array( "\n", "\n\r", "\r\n", "\r" ), "\t", $row_each_field );
|
||
|
||
$array = str_getcsv( $array, ',', '"', '\\' );
|
||
|
||
$str = ( $array && is_array( $array ) ) ? implode( ', ', $array ) : '';
|
||
|
||
$str = addslashes( $str );
|
||
|
||
$csv_data .= '"' . $str . '",';
|
||
}
|
||
$csv_data = substr_replace( $csv_data, '', -1 );
|
||
}
|
||
|
||
return $csv_data;
|
||
}
|
||
|
||
/**
|
||
* Smart Coupons export headers
|
||
*
|
||
* @param array $coupon_postmeta_headers Existing.
|
||
* @return array $coupon_postmeta_headers Including additional headers.
|
||
*/
|
||
public function wc_smart_coupons_export_headers( $coupon_postmeta_headers = array() ) {
|
||
|
||
$sc_postmeta_headers = array(
|
||
'sc_coupon_validity' => __( 'Coupon Validity', 'woocommerce-smart-coupons' ),
|
||
'validity_suffix' => __( 'Validity Suffix', 'woocommerce-smart-coupons' ),
|
||
'auto_generate_coupon' => __( 'Auto Generate Coupon', 'woocommerce-smart-coupons' ),
|
||
'coupon_title_prefix' => __( 'Coupon Title Prefix', 'woocommerce-smart-coupons' ),
|
||
'coupon_title_suffix' => __( 'Coupon Title Suffix', 'woocommerce-smart-coupons' ),
|
||
'is_pick_price_of_product' => __( 'Is Pick Price of Product', 'woocommerce-smart-coupons' ),
|
||
'sc_disable_email_restriction' => __( 'Disable Email Restriction', 'woocommerce-smart-coupons' ),
|
||
'sc_is_visible_storewide' => __( 'Coupon Is Visible Storewide', 'woocommerce-smart-coupons' ),
|
||
'sc_restrict_to_new_user' => __( 'For new user only?', 'woocommerce-smart-coupons' ),
|
||
'wc_sc_max_discount' => __( 'Max discount', 'woocommerce-smart-coupons' ),
|
||
);
|
||
|
||
if ( $this->is_wc_gte_32() ) {
|
||
$sc_postmeta_headers['wc_sc_expiry_time'] = __( 'Coupon expiry time', 'woocommerce-smart-coupons' );
|
||
}
|
||
|
||
return array_merge( $coupon_postmeta_headers, $sc_postmeta_headers );
|
||
|
||
}
|
||
|
||
/**
|
||
* Filter callback to replace {site_title} in email footer
|
||
*
|
||
* @param string $string Email footer text.
|
||
* @return string Email footer text with any replacements done.
|
||
*/
|
||
public function email_footer_replace_site_title( $string ) {
|
||
$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
|
||
return str_replace( '{site_title}', $blogname, $string );
|
||
}
|
||
|
||
/**
|
||
* Register Smart Coupons' email classes to WooCommerce's emails class list
|
||
*
|
||
* @param array $email_classes available email classes list.
|
||
* @return array $email_classes modified email classes list
|
||
*/
|
||
public function register_email_classes( $email_classes = array() ) {
|
||
|
||
include_once 'emails/class-wc-sc-email.php';
|
||
include_once 'emails/class-wc-sc-email-coupon.php';
|
||
include_once 'emails/class-wc-sc-combined-email-coupon.php';
|
||
include_once 'emails/class-wc-sc-acknowledgement-email.php';
|
||
|
||
// Add the email class to the list of email classes that WooCommerce loads.
|
||
$email_classes['WC_SC_Email_Coupon'] = new WC_SC_Email_Coupon();
|
||
$email_classes['WC_SC_Combined_Email_Coupon'] = new WC_SC_Combined_Email_Coupon();
|
||
$email_classes['WC_SC_Acknowledgement_Email'] = new WC_SC_Acknowledgement_Email();
|
||
|
||
return $email_classes;
|
||
}
|
||
|
||
/**
|
||
* Whether to hold stock for checkout or not
|
||
*
|
||
* TODO: Rework to find perfect solution
|
||
*
|
||
* @param boolean $is_hold Whether to hold or not.
|
||
* @return boolean
|
||
*/
|
||
public function hold_stock_for_checkout( $is_hold = true ) {
|
||
$is_ignore = get_option( 'wc_sc_ignore_coupon_used_warning' );
|
||
if ( 'yes' === $is_ignore ) {
|
||
return false;
|
||
}
|
||
return $is_hold;
|
||
}
|
||
|
||
/**
|
||
* Function to generate a coupon
|
||
*
|
||
* @param array $args Additional data.
|
||
* @return string|WC_Coupon
|
||
*/
|
||
public function generate_coupon( $args = array() ) {
|
||
if ( ! $this->is_wc_gte_30() ) {
|
||
return;
|
||
}
|
||
|
||
$args = array_filter( $args );
|
||
|
||
$return_type = ( ! empty( $args['return'] ) && in_array( $args['return'], array( 'code', 'object' ), true ) ) ? $args['return'] : 'object';
|
||
|
||
$coupon = null;
|
||
if ( ! empty( $args['coupon'] ) ) {
|
||
if ( is_numeric( $args['coupon'] ) || is_string( $args['coupon'] ) ) {
|
||
$coupon = new WC_Coupon( $args['coupon'] );
|
||
} elseif ( $args['coupon'] instanceof WC_Coupon ) {
|
||
$coupon = $args['coupon'];
|
||
}
|
||
} elseif ( ! empty( $args['id'] ) ) {
|
||
$coupon = new WC_Coupon( $args['id'] );
|
||
} elseif ( ! empty( $args['code'] ) ) {
|
||
$coupon = new WC_Coupon( $args['code'] );
|
||
}
|
||
|
||
$internal_keys = array(
|
||
'code',
|
||
'amount',
|
||
'discount_type',
|
||
'description',
|
||
'date_expires',
|
||
'individual_use',
|
||
'product_ids',
|
||
'excluded_product_ids',
|
||
'usage_limit',
|
||
'usage_limit_per_user',
|
||
'limit_usage_to_x_items',
|
||
'free_shipping',
|
||
'product_categories',
|
||
'excluded_product_categories',
|
||
'exclude_sale_items',
|
||
'minimum_amount',
|
||
'maximum_amount',
|
||
'email_restrictions',
|
||
'meta_data',
|
||
);
|
||
|
||
$email_restrictions = ( ! empty( $args['email_restrictions'] ) && count( $args['email_restrictions'] ) === 1 ) ? $args['email_restrictions'] : '';
|
||
|
||
$new_code = '';
|
||
if ( is_null( $coupon ) ) {
|
||
if ( ! empty( $args['discount_type'] ) && ! empty( $args['amount'] ) ) {
|
||
$new_code = $this->generate_unique_code( $email_restrictions );
|
||
$new_coupon = new WC_Coupon();
|
||
$new_coupon->set_code( $new_code );
|
||
foreach ( $args as $key => $value ) {
|
||
switch ( $key ) {
|
||
case 'code':
|
||
// do nothing.
|
||
break;
|
||
case 'meta_data':
|
||
if ( is_array( $value ) && is_callable( array( $new_coupon, 'update_meta_data' ) ) ) {
|
||
foreach ( $value as $meta ) {
|
||
$new_coupon->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' );
|
||
}
|
||
}
|
||
break;
|
||
case 'description':
|
||
$new_coupon->set_description( wp_filter_post_kses( $value ) );
|
||
break;
|
||
default:
|
||
if ( is_callable( array( $new_coupon, "set_{$key}" ) ) ) {
|
||
$new_coupon->{"set_{$key}"}( $value );
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
$new_coupon->save();
|
||
return ( 'code' === $return_type ) ? $new_code : $new_coupon;
|
||
} else {
|
||
return;
|
||
}
|
||
} else {
|
||
$is_auto_generate = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_meta' ) ) ) ? $coupon->get_meta( 'auto_generate_coupon' ) : 'no';
|
||
if ( 'yes' !== $is_auto_generate ) {
|
||
$code = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
|
||
return ( 'code' === $return_type ) ? $code : $coupon;
|
||
} else {
|
||
$new_code = $this->generate_unique_code( $email_restrictions );
|
||
$new_coupon = new WC_Coupon();
|
||
$new_coupon->set_code( $new_code );
|
||
foreach ( $internal_keys as $key ) {
|
||
if ( ! is_object( $coupon ) ) {
|
||
continue;
|
||
}
|
||
switch ( $key ) {
|
||
case 'code':
|
||
// do nothing.
|
||
break;
|
||
case 'meta_data':
|
||
$meta_data = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_meta_data' ) ) ) ? $coupon->get_meta_data() : null;
|
||
if ( ! empty( $meta_data ) ) {
|
||
foreach ( $meta_data as $meta ) {
|
||
if ( is_object( $meta ) && is_callable( array( $meta, 'get_data' ) ) ) {
|
||
$data = $meta->get_data();
|
||
if ( is_callable( array( $new_coupon, 'update_meta_data' ) ) ) {
|
||
$new_coupon->update_meta_data( $data['key'], $data['value'] );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case 'description':
|
||
$description = ( is_callable( array( $coupon, 'get_description' ) ) ) ? $coupon->get_description() : '';
|
||
if ( ! empty( $description ) && is_callable( array( $new_coupon, 'set_description' ) ) ) {
|
||
$new_coupon->set_description( wp_filter_post_kses( $description ) );
|
||
}
|
||
break;
|
||
default:
|
||
$value = ( is_callable( array( $coupon, "get_{$key}" ) ) ) ? $coupon->{"get_{$key}"}() : '';
|
||
if ( ! empty( $value ) && is_callable( array( $new_coupon, "set_{$key}" ) ) ) {
|
||
$new_coupon->{"set_{$key}"}( $value );
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
$new_coupon->save();
|
||
return ( 'code' === $return_type ) ? $new_code : $new_coupon;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Function to paint/draw coupon on a page in HTML format
|
||
*
|
||
* @param array $args Additional data including coupon info.
|
||
*/
|
||
public function paint_coupon( $args = array() ) {
|
||
if ( ! $this->is_wc_gte_30() ) {
|
||
return '';
|
||
}
|
||
if ( empty( $args['coupon'] ) ) {
|
||
return '';
|
||
}
|
||
ob_start();
|
||
|
||
if ( is_numeric( $args['coupon'] ) || is_string( $args['coupon'] ) ) {
|
||
$coupon = new WC_Coupon( $args['coupon'] );
|
||
} elseif ( $args['coupon'] instanceof WC_Coupon ) {
|
||
$coupon = $args['coupon'];
|
||
} else {
|
||
return '';
|
||
}
|
||
|
||
$with_container = ( ! empty( $args['with_container'] ) ) ? $args['with_container'] : 'no';
|
||
$with_css = ( ! empty( $args['with_css'] ) ) ? $args['with_css'] : 'no';
|
||
|
||
$design = get_option( 'wc_sc_setting_coupon_design', 'basic' );
|
||
$background_color = get_option( 'wc_sc_setting_coupon_background_color', '#39cccc' );
|
||
$foreground_color = get_option( 'wc_sc_setting_coupon_foreground_color', '#30050b' );
|
||
$third_color = get_option( 'wc_sc_setting_coupon_third_color', '#39cccc' );
|
||
$show_coupon_description = get_option( 'smart_coupons_show_coupon_description', 'no' );
|
||
$coupon_id = ( is_callable( array( $coupon, 'get_id' ) ) ) ? $coupon->get_id() : 0;
|
||
$coupon_code = ( is_callable( array( $coupon, 'get_code' ) ) ) ? $coupon->get_code() : '';
|
||
$coupon_description = ( is_callable( array( $coupon, 'description' ) ) ) ? $coupon->get_description() : '';
|
||
$coupon_amount = ( is_callable( array( $coupon, 'get_amount' ) ) ) ? $coupon->get_amount() : 0;
|
||
$is_free_shipping = ( is_callable( array( $coupon, 'get_free_shipping' ) ) ) ? wc_bool_to_string( $coupon->get_free_shipping() ) : 'no';
|
||
$expiry_date = ( is_callable( array( $coupon, 'get_date_expires' ) ) ) ? $coupon->get_date_expires() : null;
|
||
|
||
$is_callable_coupon_get_meta = $this->is_callable( $coupon, 'get_meta' );
|
||
|
||
$coupon_data = $this->get_coupon_meta_data( $coupon );
|
||
$coupon_type = ( ! empty( $coupon_data['coupon_type'] ) ) ? $coupon_data['coupon_type'] : '';
|
||
|
||
if ( 'yes' === $is_free_shipping ) {
|
||
if ( ! empty( $coupon_type ) ) {
|
||
$coupon_type .= __( ' & ', 'woocommerce-smart-coupons' );
|
||
}
|
||
$coupon_type .= __( 'Free Shipping', 'woocommerce-smart-coupons' );
|
||
}
|
||
|
||
$coupon_description = ( 'yes' === $show_coupon_description ) ? $coupon_description : '';
|
||
|
||
$is_percent = $this->is_percent_coupon( array( 'coupon_object' => $coupon ) );
|
||
|
||
if ( $expiry_date instanceof WC_DateTime ) {
|
||
$expiry_date = ( is_callable( array( $expiry_date, 'getTimestamp' ) ) ) ? $expiry_date->getTimestamp() : null;
|
||
} elseif ( ! is_int( $expiry_date ) ) {
|
||
$expiry_date = strtotime( $expiry_date );
|
||
}
|
||
|
||
if ( ! empty( $expiry_date ) && is_int( $expiry_date ) ) {
|
||
$expiry_time = ( $this->is_callable( $coupon, 'get_meta' ) ) ? (int) $coupon->get_meta( 'wc_sc_expiry_time' ) : (int) get_post_meta( $coupon_id, 'wc_sc_expiry_time', true );
|
||
if ( ! empty( $expiry_time ) ) {
|
||
$expiry_date += $expiry_time; // Adding expiry time to expiry date.
|
||
}
|
||
}
|
||
|
||
$args = array(
|
||
'coupon_object' => $coupon,
|
||
'coupon_amount' => $coupon_amount,
|
||
'amount_symbol' => ( true === $is_percent ) ? '%' : get_woocommerce_currency_symbol(),
|
||
'discount_type' => wp_strip_all_tags( $coupon_type ),
|
||
'coupon_description' => ( ! empty( $coupon_description ) ) ? $coupon_description : wp_strip_all_tags( $this->generate_coupon_description( array( 'coupon_object' => $coupon ) ) ),
|
||
'coupon_code' => $coupon_code,
|
||
'coupon_expiry' => ( ! empty( $expiry_date ) ) ? $this->get_expiration_format( $expiry_date ) : __( 'Never expires', 'woocommerce-smart-coupons' ),
|
||
'thumbnail_src' => $this->get_coupon_design_thumbnail_src(
|
||
array(
|
||
'design' => $design,
|
||
'coupon_object' => $coupon,
|
||
)
|
||
),
|
||
'classes' => 'apply_coupons_credits',
|
||
'template_id' => $design,
|
||
'is_percent' => $is_percent,
|
||
);
|
||
|
||
if ( 'yes' === $with_css ) {
|
||
?>
|
||
<div>
|
||
<style type="text/css">
|
||
:root {
|
||
--sc-color1: <?php echo esc_html( $background_color ); ?>;
|
||
--sc-color2: <?php echo esc_html( $foreground_color ); ?>;
|
||
--sc-color3: <?php echo esc_html( $third_color ); ?>;
|
||
}
|
||
</style>
|
||
<style type="text/css"><?php echo esc_html( wp_strip_all_tags( $this->get_coupon_styles( $design ), true ) ); // phpcs:ignore ?></style>
|
||
<?php
|
||
}
|
||
|
||
if ( 'yes' === $with_container ) {
|
||
?>
|
||
<div id="sc-cc">
|
||
<div class="sc-coupons-list">
|
||
<?php
|
||
}
|
||
|
||
wc_get_template( 'coupon-design/' . $design . '.php', $args, '', plugin_dir_path( WC_SC_PLUGIN_FILE ) . 'templates/' );
|
||
|
||
if ( 'yes' === $with_container ) {
|
||
?>
|
||
</div>
|
||
</div>
|
||
<?php
|
||
}
|
||
|
||
if ( 'yes' === $with_css ) {
|
||
?>
|
||
</div>
|
||
<?php
|
||
}
|
||
|
||
$html = apply_filters( 'wc_sc_coupon_html', ob_get_clean(), array_merge( $args, array( 'source' => $this ) ) );
|
||
|
||
echo $html; // phpcs:ignore
|
||
}
|
||
|
||
/**
|
||
* Add Smart Coupons' REST API Controllers
|
||
*
|
||
* @param array $namespaces Existing namespaces.
|
||
* @return array
|
||
*/
|
||
public function rest_namespace( $namespaces = array() ) {
|
||
include_once 'class-wc-sc-rest-coupons-controller.php';
|
||
$namespaces['wc/v3/sc'] = array(
|
||
'coupons' => 'WC_SC_REST_Coupons_Controller',
|
||
);
|
||
return $namespaces;
|
||
}
|
||
|
||
/**
|
||
* Get coupon column headers
|
||
*
|
||
* @return array
|
||
*/
|
||
public function get_coupon_column_headers() {
|
||
|
||
$coupon_posts_headers = array(
|
||
'post_title' => __( 'Coupon Code', 'woocommerce-smart-coupons' ),
|
||
'post_excerpt' => __( 'Post Excerpt', 'woocommerce-smart-coupons' ),
|
||
'post_status' => __( 'Post Status', 'woocommerce-smart-coupons' ),
|
||
'post_parent' => __( 'Post Parent', 'woocommerce-smart-coupons' ),
|
||
'menu_order' => __( 'Menu Order', 'woocommerce-smart-coupons' ),
|
||
'post_date' => __( 'Post Date', 'woocommerce-smart-coupons' ),
|
||
);
|
||
|
||
$coupon_postmeta_headers = apply_filters(
|
||
'wc_smart_coupons_export_headers',
|
||
array(
|
||
'discount_type' => __( 'Discount Type', 'woocommerce-smart-coupons' ),
|
||
'coupon_amount' => __( 'Coupon Amount', 'woocommerce-smart-coupons' ),
|
||
'free_shipping' => __( 'Free shipping', 'woocommerce-smart-coupons' ),
|
||
'expiry_date' => __( 'Expiry date', 'woocommerce-smart-coupons' ),
|
||
'minimum_amount' => __( 'Minimum Spend', 'woocommerce-smart-coupons' ),
|
||
'maximum_amount' => __( 'Maximum Spend', 'woocommerce-smart-coupons' ),
|
||
'individual_use' => __( 'Individual USe', 'woocommerce-smart-coupons' ),
|
||
'exclude_sale_items' => __( 'Exclude Sale Items', 'woocommerce-smart-coupons' ),
|
||
'product_ids' => __( 'Product IDs', 'woocommerce-smart-coupons' ),
|
||
'exclude_product_ids' => __( 'Exclude product IDs', 'woocommerce-smart-coupons' ),
|
||
'product_categories' => __( 'Product categories', 'woocommerce-smart-coupons' ),
|
||
'exclude_product_categories' => __( 'Exclude Product categories', 'woocommerce-smart-coupons' ),
|
||
'customer_email' => __( 'Customer Email', 'woocommerce-smart-coupons' ),
|
||
'usage_limit' => __( 'Usage Limit', 'woocommerce-smart-coupons' ),
|
||
'usage_limit_per_user' => __( 'Usage Limit Per User', 'woocommerce-smart-coupons' ),
|
||
'limit_usage_to_x_items' => __( 'Limit Usage to X Items', 'woocommerce-smart-coupons' ),
|
||
'usage_count' => __( 'Usage Count', 'woocommerce-smart-coupons' ),
|
||
'_used_by' => __( 'Used By', 'woocommerce-smart-coupons' ),
|
||
'sc_restrict_to_new_user' => __( 'For new user only?', 'woocommerce-smart-coupons' ),
|
||
)
|
||
);
|
||
|
||
$coupon_term_headers = array(
|
||
'sc_coupon_category' => __( 'Coupon Category', 'woocommerce-smart-coupons' ),
|
||
);
|
||
|
||
return array(
|
||
'posts_headers' => $coupon_posts_headers,
|
||
'postmeta_headers' => $coupon_postmeta_headers,
|
||
'term_headers' => $coupon_term_headers,
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Write to file after exporting
|
||
*
|
||
* @param array $post POST.
|
||
* @param array $get GET.
|
||
* @param array $post_ids Post ids.
|
||
*/
|
||
public function export_coupon( $post = array(), $get = array(), $post_ids = array() ) {
|
||
// Run a capability check before attempting to export coupons.
|
||
if ( ! is_admin() && ! current_user_can( 'manage_woocommerce' ) ) {
|
||
return;
|
||
}
|
||
|
||
$coupon_column_headers = $this->get_coupon_column_headers();
|
||
$coupon_posts_headers = $coupon_column_headers['posts_headers'];
|
||
$coupon_postmeta_headers = $coupon_column_headers['postmeta_headers'];
|
||
|
||
$column_headers = array_merge( $coupon_posts_headers, $coupon_postmeta_headers );
|
||
|
||
if ( ! empty( $post ) ) {
|
||
$data = $this->generate_coupons_code( $post, '', '', array() );
|
||
} elseif ( ! empty( $get ) ) {
|
||
$data = $this->generate_coupons_code( '', $get, $post_ids, $coupon_postmeta_headers );
|
||
}
|
||
|
||
$file_data = $this->export_coupon_csv( $column_headers, $data );
|
||
|
||
if ( ( isset( $post['generate_and_import'] ) && ! empty( $post['smart_coupons_generate_action'] ) && 'sc_export_and_import' === $post['smart_coupons_generate_action'] ) || isset( $get['export_coupons'] ) ) {
|
||
|
||
if ( ob_get_level() ) {
|
||
$levels = ob_get_level();
|
||
for ( $i = 0; $i < $levels; $i++ ) {
|
||
ob_end_clean();
|
||
}
|
||
} else {
|
||
ob_end_clean();
|
||
}
|
||
nocache_headers();
|
||
header( 'X-Robots-Tag: noindex, nofollow', true );
|
||
header( 'Content-Type: text/x-csv; charset=UTF-8' );
|
||
header( 'Content-Description: File Transfer' );
|
||
header( 'Content-Transfer-Encoding: binary' );
|
||
header( 'Content-Disposition: attachment; filename="' . sanitize_file_name( $file_data['file_name'] ) . '";' );
|
||
|
||
echo $file_data['file_content']; // phpcs:ignore
|
||
exit;
|
||
} else {
|
||
|
||
// Proceed only if there is no directory permission related issue.
|
||
if ( ! isset( $file_data['error'] ) ) {
|
||
// Create CSV file.
|
||
$csv_folder = $file_data['wp_upload_dir'];
|
||
$filename = str_replace( array( '\'', '"', ',', ';', '<', '>', '/', ':' ), '', $file_data['file_name'] );
|
||
$csvfilename = $csv_folder . $filename;
|
||
$fp = fopen( $csvfilename, 'w' ); // phpcs:ignore
|
||
if ( false !== $fp ) {
|
||
fwrite( $fp , $file_data['file_content'] ); // phpcs:ignore
|
||
fclose( $fp ); // phpcs:ignore
|
||
}
|
||
|
||
return $csvfilename;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Function to enqueue additional styles & scripts for Smart Coupons in admin
|
||
*/
|
||
public function smart_coupon_styles_and_scripts() {
|
||
global $post, $pagenow;
|
||
|
||
if ( ! empty( $pagenow ) ) {
|
||
$show_css_for_smart_coupon_tab = false;
|
||
$get_post_type = ( ! empty( $post->post_type ) ) ? $post->post_type : ( ( ! empty( $_GET['post_type'] ) ) ? wc_clean( wp_unslash( $_GET['post_type'] ) ) : '' ); // phpcs:ignore
|
||
$get_page = ( ! empty( $_GET['page'] ) ) ? wc_clean( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore
|
||
if ( ( 'edit.php' === $pagenow || 'post.php' === $pagenow || 'post-new.php' === $pagenow ) && in_array( $get_post_type, array( 'shop_coupon', 'product', 'product-variation' ), true ) ) {
|
||
$show_css_for_smart_coupon_tab = true;
|
||
}
|
||
if ( 'admin.php' === $pagenow && 'wc-smart-coupons' === $get_page ) {
|
||
$show_css_for_smart_coupon_tab = true;
|
||
}
|
||
if ( $show_css_for_smart_coupon_tab ) {
|
||
if ( ! wp_style_is( 'smart-coupon' ) ) {
|
||
wp_enqueue_style( 'smart-coupon' );
|
||
}
|
||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||
wp_register_style( 'smart-coupons-admin', untrailingslashit( plugins_url( '/', WC_SC_PLUGIN_FILE ) ) . '/assets/css/smart-coupons-admin' . $suffix . '.css', array(), $this->plugin_data['Version'] );
|
||
wp_enqueue_style( 'smart-coupons-admin' );
|
||
}
|
||
}
|
||
|
||
if ( ! empty( $post->post_type ) && 'product' === $post->post_type ) {
|
||
if ( wp_script_is( 'select2' ) ) {
|
||
wp_localize_script(
|
||
'select2',
|
||
'smart_coupons_select_params',
|
||
array(
|
||
'i18n_matches_1' => _x( 'One result is available, press enter to select it.', 'enhanced select', 'woocommerce-smart-coupons' ),
|
||
'i18n_matches_n' => _x( '%qty% results are available, use up and down arrow keys to navigate.', 'enhanced select', 'woocommerce-smart-coupons' ),
|
||
'i18n_no_matches' => _x( 'No matches found', 'enhanced select', 'woocommerce-smart-coupons' ),
|
||
'i18n_ajax_error' => _x( 'Loading failed', 'enhanced select', 'woocommerce-smart-coupons' ),
|
||
'i18n_input_too_short_1' => _x( 'Please enter 1 or more characters', 'enhanced select', 'woocommerce-smart-coupons' ),
|
||
'i18n_input_too_short_n' => _x( 'Please enter %qty% or more characters', 'enhanced select', 'woocommerce-smart-coupons' ),
|
||
'i18n_input_too_long_1' => _x( 'Please delete 1 character', 'enhanced select', 'woocommerce-smart-coupons' ),
|
||
'i18n_input_too_long_n' => _x( 'Please delete %qty% characters', 'enhanced select', 'woocommerce-smart-coupons' ),
|
||
'i18n_selection_too_long_1' => _x( 'You can only select 1 item', 'enhanced select', 'woocommerce-smart-coupons' ),
|
||
'i18n_selection_too_long_n' => _x( 'You can only select %qty% items', 'enhanced select', 'woocommerce-smart-coupons' ),
|
||
'i18n_load_more' => _x( 'Loading more results…', 'enhanced select', 'woocommerce-smart-coupons' ),
|
||
'i18n_searching' => _x( 'Searching…', 'enhanced select', 'woocommerce-smart-coupons' ),
|
||
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
||
'search_products_nonce' => wp_create_nonce( 'search-products' ),
|
||
'search_customers_nonce' => wp_create_nonce( 'search-customers' ),
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Add if cache key doesn't exists
|
||
*
|
||
* @param string $key The cache key.
|
||
*/
|
||
public function maybe_add_cache_key( $key = '' ) {
|
||
if ( ! empty( $key ) ) {
|
||
$all_cache_key = get_option( 'wc_sc_all_cache_key' );
|
||
if ( false !== $all_cache_key ) {
|
||
if ( empty( $all_cache_key ) || ! is_array( $all_cache_key ) ) {
|
||
$all_cache_key = array();
|
||
}
|
||
if ( ! in_array( $key, $all_cache_key, true ) ) {
|
||
$all_cache_key[] = $key;
|
||
update_option( 'wc_sc_all_cache_key', $all_cache_key, 'no' );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Make meta data of this plugin, protected
|
||
*
|
||
* @param bool $protected Is protected.
|
||
* @param string $meta_key the meta key.
|
||
* @param string $meta_type The meta type.
|
||
* @return bool $protected
|
||
*/
|
||
public function make_sc_meta_protected( $protected, $meta_key, $meta_type ) {
|
||
$sc_meta = array(
|
||
'auto_generate_coupon',
|
||
'coupon_sent',
|
||
'coupon_title_prefix',
|
||
'coupon_title_suffix',
|
||
'generated_from_order_id',
|
||
'gift_receiver_email',
|
||
'gift_receiver_message',
|
||
'gift_sending_timestamp',
|
||
'is_gift',
|
||
'is_pick_price_of_product',
|
||
'sc_called_credit_details',
|
||
'sc_coupon_receiver_details',
|
||
'sc_coupon_validity',
|
||
'sc_disable_email_restriction',
|
||
'sc_is_visible_storewide',
|
||
'send_coupons_on_renewals',
|
||
'smart_coupons_contribution',
|
||
'temp_gift_card_receivers_emails',
|
||
'validity_suffix',
|
||
'sc_restrict_to_new_user',
|
||
'wc_sc_schedule_gift_sending',
|
||
'wc_sc_max_discount',
|
||
'wc_sc_expiry_time',
|
||
'wc_sc_product_attribute_ids',
|
||
'wc_sc_exclude_product_attribute_ids',
|
||
);
|
||
if ( in_array( $meta_key, $sc_meta, true ) ) {
|
||
return true;
|
||
}
|
||
return $protected;
|
||
}
|
||
|
||
/**
|
||
* Get the order from the PayPal 'Custom' variable.
|
||
*
|
||
* Credit: WooCommerce
|
||
*
|
||
* @param string $raw_custom JSON Data passed back by PayPal.
|
||
* @return bool|WC_Order object
|
||
*/
|
||
public function get_paypal_order( $raw_custom ) {
|
||
|
||
if ( ! class_exists( 'WC_Gateway_Paypal' ) ) {
|
||
include_once WC()->plugin_path() . '/includes/gateways/paypal/class-wc-gateway-paypal.php';
|
||
}
|
||
// We have the data in the correct format, so get the order.
|
||
if ( ( $custom = json_decode( $raw_custom ) ) && is_object( $custom ) ) { // phpcs:ignore
|
||
$order_id = $custom->order_id;
|
||
$order_key = $custom->order_key;
|
||
|
||
// Fallback to serialized data if safe. This is @deprecated in 2.3.11.
|
||
} elseif ( preg_match( '/^a:2:{/', $raw_custom ) && ! preg_match( '/[CO]:\+?[0-9]+:"/', $raw_custom ) && ( $custom = maybe_unserialize( $raw_custom ) ) ) { // phpcs:ignore
|
||
$order_id = $custom[0];
|
||
$order_key = $custom[1];
|
||
|
||
// Nothing was found.
|
||
} else {
|
||
WC_Gateway_Paypal::log( 'Error: Order ID and key were not found in "custom".' );
|
||
return false;
|
||
}
|
||
|
||
if ( ! $order = wc_get_order( $order_id ) ) { // phpcs:ignore
|
||
// We have an invalid $order_id, probably because invoice_prefix has changed.
|
||
$order_id = wc_get_order_id_by_order_key( $order_key );
|
||
$order = wc_get_order( $order_id );
|
||
}
|
||
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$_order_key = ( ! empty( $order ) && is_callable( array( $order, 'get_order_key' ) ) ) ? $order->get_order_key() : '';
|
||
} else {
|
||
$_order_key = ( ! empty( $order->order_key ) ) ? $order->order_key : '';
|
||
}
|
||
|
||
if ( ! $order || $_order_key !== $order_key ) {
|
||
WC_Gateway_Paypal::log( 'Error: Order Keys do not match.' );
|
||
return false;
|
||
}
|
||
|
||
return $order;
|
||
}
|
||
|
||
/**
|
||
* Get all coupon styles
|
||
*
|
||
* @return array
|
||
*/
|
||
public function get_wc_sc_coupon_styles() {
|
||
|
||
$all_styles = array(
|
||
'inner' => __( 'Style 1', 'woocommerce-smart-coupons' ),
|
||
'round-corner' => __( 'Style 2', 'woocommerce-smart-coupons' ),
|
||
'round-dashed' => __( 'Style 3', 'woocommerce-smart-coupons' ),
|
||
'outer-dashed' => __( 'Style 4', 'woocommerce-smart-coupons' ),
|
||
'left' => __( 'Style 5', 'woocommerce-smart-coupons' ),
|
||
'bottom' => __( 'Style 6', 'woocommerce-smart-coupons' ),
|
||
'custom-design' => __( 'Custom Style', 'woocommerce-smart-coupons' ),
|
||
);
|
||
|
||
return apply_filters( 'wc_sc_get_wc_sc_coupon_styles', $all_styles );
|
||
|
||
}
|
||
|
||
/**
|
||
* Get coupon display styles
|
||
*
|
||
* @param string $style_name The style name.
|
||
* @param array $args Additional arguments.
|
||
* @return string
|
||
*/
|
||
public function get_coupon_styles( $style_name = '', $args = array() ) {
|
||
|
||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||
|
||
$is_email = ( ! empty( $args['is_email'] ) ) ? $args['is_email'] : 'no';
|
||
|
||
ob_start();
|
||
|
||
if ( 'custom-design' === $style_name ) {
|
||
$custom_design_css = get_option( 'wc_sc_custom_design_css', '' );
|
||
echo $custom_design_css; // phpcs:ignore
|
||
} elseif ( 'email-coupon' === $style_name ) {
|
||
$file = trailingslashit( WP_PLUGIN_DIR . '/' . WC_SC_PLUGIN_DIRNAME ) . 'assets/css/wc-sc-style-' . $style_name . $suffix . '.css';
|
||
if ( file_exists( $file ) ) {
|
||
include $file;
|
||
} else {
|
||
/* translators: File path */
|
||
$this->log( 'error', sprintf( __( 'File not found %s', 'woocommerce-smart-coupons' ), '<code>' . $file . '</code>' ) . ' ' . __FILE__ . ' ' . __LINE__ );
|
||
}
|
||
} else {
|
||
$file = trailingslashit( WP_PLUGIN_DIR . '/' . WC_SC_PLUGIN_DIRNAME ) . 'assets/css/smart-coupon-designs.css';
|
||
if ( file_exists( $file ) ) {
|
||
include $file;
|
||
} else {
|
||
/* translators: File path */
|
||
$this->log( 'error', sprintf( __( 'File not found %s', 'woocommerce-smart-coupons' ), '<code>' . $file . '</code>' ) . ' ' . __FILE__ . ' ' . __LINE__ );
|
||
}
|
||
}
|
||
|
||
$styles = ob_get_clean();
|
||
|
||
if ( 'yes' === $is_email ) {
|
||
$styles = str_replace( array( ':before', ':hover', ':focus', ':active' ), array( '-pseudo-before', '-pseudo-hover', '-pseudo-focus', '-pseudo-active' ), $styles );
|
||
}
|
||
|
||
return apply_filters( 'wc_sc_get_coupon_styles', $styles, $style_name, $args );
|
||
|
||
}
|
||
|
||
/**
|
||
* Insert a setting or an array of settings after another specific setting by its ID.
|
||
*
|
||
* @since 1.2.1
|
||
* @param array $settings The original list of settings.
|
||
* @param string $insert_after_setting_id The setting id to insert the new setting after.
|
||
* @param array $new_setting The new setting to insert. Can be a single setting or an array of settings.
|
||
* @param string $insert_type The type of insert to perform. Can be 'single_setting' or 'multiple_settings'. Optional. Defaults to a single setting insert.
|
||
*
|
||
* @credit: WooCommerce Subscriptions
|
||
*/
|
||
public static function insert_setting_after( &$settings, $insert_after_setting_id, $new_setting, $insert_type = 'single_setting' ) {
|
||
if ( ! is_array( $settings ) ) {
|
||
return;
|
||
}
|
||
|
||
$original_settings = $settings;
|
||
$settings = array();
|
||
|
||
foreach ( $original_settings as $setting ) {
|
||
$settings[] = $setting;
|
||
|
||
if ( isset( $setting['id'] ) && $insert_after_setting_id === $setting['id'] ) {
|
||
if ( 'single_setting' === $insert_type ) {
|
||
$settings[] = $new_setting;
|
||
} else {
|
||
$settings = array_merge( $settings, $new_setting );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* To generate unique id
|
||
*
|
||
* Credit: WooCommerce
|
||
*/
|
||
public function generate_unique_id() {
|
||
|
||
require_once ABSPATH . 'wp-includes/class-phpass.php';
|
||
$hasher = new PasswordHash( 8, false );
|
||
return md5( $hasher->get_random_bytes( 32 ) );
|
||
|
||
}
|
||
|
||
/**
|
||
* To get cookie life
|
||
*/
|
||
public function get_cookie_life() {
|
||
|
||
$life = get_option( 'wc_sc_coupon_cookie_life', 180 );
|
||
|
||
return apply_filters( 'wc_sc_coupon_cookie_life', time() + ( 60 * 60 * 24 * $life ) );
|
||
|
||
}
|
||
|
||
/**
|
||
* Show notice on admin panel about minimum required version of WooCommerce
|
||
*/
|
||
public function minimum_woocommerce_version_requirement() {
|
||
if ( $this->is_wc_gte_30() ) {
|
||
return;
|
||
}
|
||
|
||
$plugin_data = self::get_smart_coupons_plugin_data();
|
||
$plugin_name = $plugin_data['Name'];
|
||
?>
|
||
<div class="updated error">
|
||
<p>
|
||
<?php
|
||
echo '<strong>' . esc_html__( 'Important', 'woocommerce-smart-coupons' ) . ':</strong> ' . esc_html( $plugin_name ) . ' ' . esc_html__( 'is active but it will only work with WooCommerce 3.0.0+.', 'woocommerce-smart-coupons' ) . ' <a href="' . esc_url( admin_url( 'plugins.php?plugin_status=upgrade' ) ) . '" target="_blank" >' . esc_html__( 'Please update WooCommerce to the latest version', 'woocommerce-smart-coupons' ) . '</a>.';
|
||
?>
|
||
</p>
|
||
</div>
|
||
<?php
|
||
}
|
||
|
||
/**
|
||
* Function to fetch plugin's data
|
||
*/
|
||
public static function get_smart_coupons_plugin_data() {
|
||
return get_plugin_data( WC_SC_PLUGIN_FILE );
|
||
}
|
||
|
||
/**
|
||
* Function to get plugin's version
|
||
*/
|
||
public function get_smart_coupons_version() {
|
||
$plugin_data = self::get_smart_coupons_plugin_data();
|
||
return isset( $plugin_data['Version'] ) ? $plugin_data['Version'] : false;
|
||
}
|
||
|
||
|
||
/**
|
||
* Function to get singular/plural name for store credit
|
||
*/
|
||
public function define_label_for_store_credit() {
|
||
global $store_credit_label;
|
||
|
||
if ( empty( $store_credit_label ) || ! is_array( $store_credit_label ) ) {
|
||
$store_credit_label = array();
|
||
}
|
||
|
||
if ( empty( $store_credit_label['singular'] ) ) {
|
||
$store_credit_label['singular'] = get_option( 'sc_store_credit_singular_text' );
|
||
}
|
||
|
||
if ( empty( $store_credit_label['plural'] ) ) {
|
||
$store_credit_label['plural'] = get_option( 'sc_store_credit_plural_text' );
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* Function to get length of auto generated coupon code
|
||
*/
|
||
public function get_coupon_code_length() {
|
||
$coupon_code_length = get_option( 'wc_sc_coupon_code_length' );
|
||
return ! empty( $coupon_code_length ) ? $coupon_code_length : 13; // Default coupon code length is 13.
|
||
}
|
||
|
||
/**
|
||
* Function to get coupon codes used in an order
|
||
*
|
||
* @param mixed $order Order object or order ID.
|
||
* @return array $coupon_codes coupon codes used in order.
|
||
*/
|
||
public function get_coupon_codes( $order = '' ) {
|
||
$coupon_codes = array();
|
||
if ( ! empty( $order ) ) {
|
||
// Try to load order using ID.
|
||
if ( is_int( $order ) ) {
|
||
$order = wc_get_order( $order );
|
||
}
|
||
|
||
if ( is_a( $order, 'WC_Order' ) ) {
|
||
if ( $this->is_wc_gte_37() ) {
|
||
$coupon_codes = is_callable( array( $order, 'get_coupon_codes' ) ) ? $order->get_coupon_codes() : array();
|
||
} else {
|
||
$coupon_codes = is_callable( array( $order, 'get_used_coupons' ) ) ? $order->get_used_coupons() : array();
|
||
}
|
||
}
|
||
}
|
||
return $coupon_codes;
|
||
}
|
||
|
||
/**
|
||
* Function to get default CSS for custom coupon design
|
||
*
|
||
* @return string $default_css Default custom CSS.
|
||
*/
|
||
public function get_custom_design_default_css() {
|
||
$default_css = '/* Coupon style for custom-design */
|
||
.coupon-container.custom-design {
|
||
background: #39cccc;
|
||
}
|
||
|
||
.coupon-container.custom-design .coupon-content {
|
||
border: solid 1px lightgrey;
|
||
color: #30050b;
|
||
}';
|
||
return apply_filters( 'wc_sc_coupon_custom_design_default_css', $default_css );
|
||
}
|
||
|
||
/**
|
||
* Function to check if coupon email is enabled or not
|
||
*
|
||
* TODO: Can be removed in future
|
||
*
|
||
* @param string $template The template's setting to check for.
|
||
* @return boolean $is_email_enabled Is email enabled
|
||
*/
|
||
public function is_email_template_enabled( $template = 'send' ) {
|
||
|
||
if ( 'combine' === $template ) {
|
||
$wc_email_settings_key = 'woocommerce_wc_sc_combined_email_coupon_settings';
|
||
$sc_email_setting_key = 'smart_coupons_combine_emails';
|
||
$default = 'no';
|
||
} else {
|
||
$wc_email_settings_key = 'woocommerce_wc_sc_email_coupon_settings';
|
||
$sc_email_setting_key = 'smart_coupons_is_send_email';
|
||
$default = 'yes';
|
||
}
|
||
|
||
$is_email_enabled = '';
|
||
|
||
$wc_email_settings = get_option( $wc_email_settings_key );
|
||
|
||
// If setting is not found in WC Email settings fetch it from SC admin settings.
|
||
if ( false === $wc_email_settings ) {
|
||
$is_email_enabled = get_option( $sc_email_setting_key, $default );
|
||
} elseif ( is_array( $wc_email_settings ) && ! empty( $wc_email_settings ) ) {
|
||
$is_email_enabled = ( isset( $wc_email_settings['enabled'] ) && ! empty( $wc_email_settings['enabled'] ) ) ? $wc_email_settings['enabled'] : $default;
|
||
}
|
||
|
||
return $is_email_enabled;
|
||
}
|
||
|
||
/**
|
||
* Function to check if store credit discount is inclusive of tax.
|
||
*
|
||
* @return string $sc_include_tax Is store credit includes tax
|
||
*/
|
||
public function is_store_credit_include_tax() {
|
||
|
||
$sc_include_tax = 'no';
|
||
$prices_include_tax = wc_prices_include_tax();
|
||
|
||
// Discount can only be inclusive of tax if prices are inclusive of tax and apply before tax is enabled.
|
||
if ( true === $prices_include_tax ) {
|
||
$apply_before_tax = get_option( 'woocommerce_smart_coupon_apply_before_tax', 'no' );
|
||
if ( 'yes' === $apply_before_tax ) {
|
||
// Get SC setting for include tax.
|
||
$sc_include_tax = get_option( 'woocommerce_smart_coupon_include_tax', 'no' );
|
||
}
|
||
}
|
||
return $sc_include_tax;
|
||
}
|
||
|
||
/**
|
||
* Whether to generate store credit including tax amount or not
|
||
*
|
||
* @return boolean
|
||
*/
|
||
public function is_generated_store_credit_includes_tax() {
|
||
$is_include_tax = get_option( 'wc_sc_generated_store_credit_includes_tax', 'no' );
|
||
return apply_filters( 'wc_sc_is_generated_store_credit_includes_tax', wc_string_to_bool( $is_include_tax ), array( 'source' => $this ) );
|
||
}
|
||
|
||
/**
|
||
* Get emoji
|
||
*
|
||
* @return string
|
||
*/
|
||
public function get_emoji() {
|
||
$emojis = array(
|
||
11088 => '⭐',
|
||
127775 => '🌟',
|
||
127873 => '🎁',
|
||
127881 => '🎉',
|
||
127882 => '🎊',
|
||
127941 => '🏅',
|
||
127942 => '🏆',
|
||
127991 => '🏷',
|
||
128075 => '👋',
|
||
128076 => '👌',
|
||
128077 => '👍',
|
||
128079 => '👏',
|
||
128081 => '👑',
|
||
128142 => '💎',
|
||
128165 => '💥',
|
||
128276 => '🔔',
|
||
128293 => '🔥',
|
||
128640 => '🚀',
|
||
129311 => '🤟',
|
||
129321 => '🤩',
|
||
);
|
||
$key = array_rand( $emojis );
|
||
return $emojis[ $key ];
|
||
}
|
||
|
||
/**
|
||
* Get coupon titles for product
|
||
*
|
||
* @param array $args Additional data.
|
||
* @return array
|
||
*/
|
||
public function get_coupon_titles( $args = array() ) {
|
||
$coupon_titles = array();
|
||
if ( empty( $args ) ) {
|
||
return $coupon_titles;
|
||
}
|
||
$product = ( ! empty( $args['product_object'] ) && is_a( $args['product_object'], 'WC_Product' ) ) ? $args['product_object'] : null;
|
||
if ( is_null( $product ) ) {
|
||
return $coupon_titles;
|
||
}
|
||
$coupon_titles = ( is_callable( array( $product, 'get_meta' ) ) ) ? $product->get_meta( '_coupon_title' ) : array();
|
||
if ( empty( $coupon_titles ) ) {
|
||
$parent_id = ( is_callable( array( $product, 'get_parent_id' ) ) ) ? $product->get_parent_id() : 0;
|
||
if ( empty( $parent_id ) ) {
|
||
return array();
|
||
}
|
||
$parent_product = ( function_exists( 'wc_get_product' ) ) ? wc_get_product( $parent_id ) : null;
|
||
$coupon_titles = ( $this->is_callable( $parent_product, 'get_meta' ) ) ? $parent_product->get_meta( '_coupon_title' ) : $this->get_post_meta( $parent_id, '_coupon_title', true );
|
||
}
|
||
if ( empty( $coupon_titles ) && ! is_array( $coupon_titles ) ) {
|
||
return array();
|
||
}
|
||
return $coupon_titles;
|
||
}
|
||
|
||
/**
|
||
* Function to copy coupon meta data and save to new coupon.
|
||
*
|
||
* @param array $coupon_data Array of new coupon id and old coupon object.
|
||
* @param array $meta_keys Meta keys.
|
||
*/
|
||
public function copy_coupon_meta_data( $coupon_data = array(), $meta_keys = array() ) {
|
||
|
||
$new_coupon_id = ( ! empty( $coupon_data['new_coupon_id'] ) ) ? absint( $coupon_data['new_coupon_id'] ) : 0;
|
||
$coupon = ( ! empty( $coupon_data['ref_coupon'] ) ) ? $coupon_data['ref_coupon'] : false;
|
||
|
||
if ( empty( $new_coupon_id ) || empty( $coupon ) ) {
|
||
return;
|
||
}
|
||
|
||
if ( ! empty( $new_coupon_id ) && is_array( $meta_keys ) && ! empty( $meta_keys ) ) {
|
||
$new_coupon = new WC_Coupon( $new_coupon_id );
|
||
$is_callable_new_coupon_update_meta = $this->is_callable( $new_coupon, 'update_meta_data' );
|
||
$is_callable_coupon_get_meta = $this->is_callable( $coupon, 'get_meta' );
|
||
// Save each meta to new coupon.
|
||
foreach ( $meta_keys as $meta_key ) {
|
||
$update = false;
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$meta_value = ( true === $is_callable_coupon_get_meta ) ? $coupon->get_meta( $meta_key ) : '';
|
||
$update = true;
|
||
} else {
|
||
$old_coupon_id = ( ! empty( $coupon->id ) ) ? $coupon->id : 0;
|
||
if ( ! empty( $old_coupon_id ) ) { // This will confirm that the coupon exists.
|
||
$meta_value = get_post_meta( $old_coupon_id, $meta_key, true );
|
||
$update = true;
|
||
}
|
||
}
|
||
if ( true === $update ) {
|
||
if ( true === $is_callable_new_coupon_update_meta ) {
|
||
$new_coupon->update_meta_data( $meta_key, $meta_value );
|
||
} else {
|
||
update_post_meta( $new_coupon_id, $meta_key, $meta_value );
|
||
}
|
||
}
|
||
}
|
||
if ( $this->is_callable( $new_coupon, 'save' ) ) {
|
||
$new_coupon->save();
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check given coupon exists.
|
||
*
|
||
* @param string $coupon_code Coupon code.
|
||
* @return bool
|
||
*
|
||
* Credit: WooCommerce
|
||
*/
|
||
public function sc_coupon_exists( $coupon_code = '' ) {
|
||
if ( empty( $coupon_code ) ) {
|
||
return false;
|
||
}
|
||
$coupon = new WC_Coupon( $coupon_code );
|
||
return (bool) $coupon->get_id() || $coupon->get_virtual();
|
||
}
|
||
|
||
/**
|
||
* Function to get pending order statuses
|
||
*
|
||
* @return array
|
||
*/
|
||
public function get_pending_statuses() {
|
||
return apply_filters( 'wc_sc_pending_order_statuses', array( 'on-hold', 'auto-draft', 'pending' ), array( 'source' => $this ) );
|
||
}
|
||
|
||
/**
|
||
* Checking subtotal is eligible for free shipping method
|
||
*
|
||
* @param bool $is_available true/false.
|
||
* @param array $package Shipping package.
|
||
* @param object $free_shipping free shipping object.
|
||
* @return mixed|void
|
||
*/
|
||
public function is_eligible_for_free_shipping( $is_available = false, $package = array(), $free_shipping = null ) {
|
||
|
||
// If free shipping is invalid already, no need for further checks.
|
||
if ( false === $is_available || ! is_object( $free_shipping ) ) {
|
||
return $is_available;
|
||
}
|
||
|
||
$apply_before_tax = get_option( 'woocommerce_smart_coupon_apply_before_tax', 'no' );
|
||
|
||
if ( $this->is_wc_gte_30() && 'yes' === $apply_before_tax ) {
|
||
return $is_available;
|
||
}
|
||
|
||
$has_coupon = false;
|
||
$has_met_min_amount = false;
|
||
$has_smart_coupon = false;
|
||
$coupon_usable_amount = 0;
|
||
$coupons = ( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'get_coupons' ) ) ) ? WC()->cart->get_coupons() : array();
|
||
$free_shipping_condition = ! empty( $free_shipping->requires ) ? $free_shipping->requires : '';
|
||
$free_shipping_ignore_discounts = ! empty( $free_shipping->ignore_discounts ) ? $free_shipping->ignore_discounts : '';
|
||
$free_shipping_min_amount = ! empty( $free_shipping->min_amount ) ? $free_shipping->min_amount : 0;
|
||
|
||
if ( ! empty( $coupons ) ) {
|
||
|
||
foreach ( $coupons as $coupon_code => $coupon ) {
|
||
$discount_type = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_discount_type' ) ) ) ? $coupon->get_discount_type() : '';
|
||
if ( 'smart_coupon' === $discount_type ) {
|
||
$has_smart_coupon = true;
|
||
$coupon_usable_amount += $this->get_amount( $coupon, true );
|
||
}
|
||
if ( in_array( $free_shipping_condition, array( 'coupon', 'either', 'both' ), true ) ) {
|
||
$coupon_is_valid = ( is_object( $coupon ) && is_callable( array( $coupon, 'is_valid' ) ) ) ? $coupon->is_valid() : false;
|
||
$coupon_get_free_shipping = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_free_shipping' ) ) ) ? $coupon->get_free_shipping() : false;
|
||
if ( true === $coupon_is_valid && true === $coupon_get_free_shipping ) {
|
||
$has_coupon = true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( false === $has_smart_coupon ) {
|
||
return $is_available;
|
||
}
|
||
|
||
if ( in_array( $free_shipping_condition, array( 'min_amount', 'either', 'both' ), true ) ) {
|
||
|
||
$total = ( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'get_displayed_subtotal' ) ) ) ? WC()->cart->get_displayed_subtotal() : 0;
|
||
$display_prices_including_tax = ( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'display_prices_including_tax' ) ) ) ? WC()->cart->display_prices_including_tax() : false;
|
||
|
||
if ( $display_prices_including_tax ) {
|
||
$get_discount_tax = ( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'get_discount_tax' ) ) ) ? WC()->cart->get_discount_tax() : 0;
|
||
$total = $total - $get_discount_tax;
|
||
}
|
||
|
||
if ( 'no' === $free_shipping_ignore_discounts ) {
|
||
$get_discount_total = ( is_object( WC()->cart ) && is_callable( array( WC()->cart, 'get_discount_total' ) ) ) ? WC()->cart->get_discount_total() : 0;
|
||
$total = $total - $get_discount_total;
|
||
$total = $total - $coupon_usable_amount;
|
||
}
|
||
|
||
$total = round( ( $total ), get_option( 'woocommerce_price_num_decimals', 2 ) );
|
||
|
||
if ( $total >= $free_shipping_min_amount ) {
|
||
$has_met_min_amount = true;
|
||
}
|
||
}
|
||
|
||
switch ( $free_shipping->requires ) {
|
||
case 'min_amount':
|
||
$is_available = $has_met_min_amount;
|
||
break;
|
||
case 'coupon':
|
||
$is_available = $has_coupon;
|
||
break;
|
||
case 'both':
|
||
$is_available = $has_met_min_amount && $has_coupon;
|
||
break;
|
||
case 'either':
|
||
$is_available = $has_met_min_amount || $has_coupon;
|
||
break;
|
||
default:
|
||
$is_available = true;
|
||
break;
|
||
}
|
||
|
||
return $is_available;
|
||
}
|
||
|
||
/**
|
||
* Smart coupon system status section in wc system status.
|
||
*
|
||
* @return void
|
||
*/
|
||
public function smart_coupons_system_status_report() {
|
||
$smart_coupons_settings = array();
|
||
|
||
$max_coupon_to_show = get_option( 'wc_sc_setting_max_coupon_to_show' );
|
||
$coupon_code_length = get_option( 'wc_sc_coupon_code_length' );
|
||
$valid_order_statuses = get_option( 'wc_sc_valid_order_statuses_for_coupon_auto_generation' );
|
||
$is_include_tax = get_option( 'wc_sc_generated_store_credit_includes_tax' );
|
||
$apply_before_tax = get_option( 'woocommerce_smart_coupon_apply_before_tax' );
|
||
$sc_include_tax = get_option( 'woocommerce_smart_coupon_include_tax' );
|
||
$is_delete_smart_coupon_after_usage = get_option( 'woocommerce_delete_smart_coupon_after_usage' );
|
||
$is_send_email = get_option( 'smart_coupons_is_send_email' );
|
||
$is_print = get_option( 'smart_coupons_is_print_coupon' );
|
||
$sell_sc_at_less_price = get_option( 'smart_coupons_sell_store_credit_at_less_price' );
|
||
$pay_from_credit_of_original_order = get_option( 'pay_from_smart_coupon_of_original_order' );
|
||
$stop_recursive_coupon_generation = get_option( 'stop_recursive_coupon_generation' );
|
||
$is_show_coupon_receiver_form = get_option( 'smart_coupons_display_coupon_receiver_details_form' );
|
||
$schedule_store_credit = get_option( 'smart_coupons_schedule_store_credit' );
|
||
$combine_emails = get_option( 'smart_coupons_combine_emails' );
|
||
$enable_taxes = get_option( 'woocommerce_calc_taxes' );
|
||
$price_entered_with_tax_type = get_option( 'woocommerce_prices_include_tax' );
|
||
$round_at_subtotal = get_option( 'woocommerce_tax_round_at_subtotal' );
|
||
$tax_display_shop = get_option( 'woocommerce_tax_display_shop' );
|
||
$tax_display_cart = get_option( 'woocommerce_tax_display_cart' );
|
||
$tax_total_display = get_option( 'woocommerce_tax_total_display' );
|
||
$wc_enable_coupons = get_option( 'woocommerce_enable_coupons' );
|
||
$calc_discounts_sequentially = get_option( 'woocommerce_calc_discounts_sequentially' );
|
||
$wc_sc_dashboard_endpoint = get_option( 'woocommerce_myaccount_wc_sc_dashboard_endpoint', 'wc-smart-coupons' );
|
||
|
||
if ( is_array( $valid_order_statuses ) && ! empty( $valid_order_statuses ) ) {
|
||
$valid_order_statuses = implode( ', ', $valid_order_statuses );
|
||
}
|
||
|
||
$auto_generated_coupon_email = $this->is_email_template_enabled();
|
||
$combined_email_coupon_enabled = $this->is_email_template_enabled( 'combine' );
|
||
|
||
$smart_coupons_settings = array(
|
||
__( 'Number of coupons to show', 'woocommerce-smart-coupons' ) => $max_coupon_to_show,
|
||
__( 'Number of characters in auto-generated coupon code', 'woocommerce-smart-coupons' ) => $coupon_code_length,
|
||
__( 'Valid order status for auto-generating coupon', 'woocommerce-smart-coupons' ) => $valid_order_statuses,
|
||
__( 'Include tax in the amount of the generated gift card', 'woocommerce-smart-coupons' ) => $is_include_tax,
|
||
__( 'Deduct credit/gift before doing tax calculations', 'woocommerce-smart-coupons' ) => $apply_before_tax,
|
||
__( 'Gift Card discount is inclusive of tax', 'woocommerce-smart-coupons' ) => $sc_include_tax,
|
||
__( 'Automatic deletion', 'woocommerce-smart-coupons' ) => $is_delete_smart_coupon_after_usage,
|
||
__( 'Coupon emails', 'woocommerce-smart-coupons' ) => $is_send_email,
|
||
__( 'Printing coupons', 'woocommerce-smart-coupons' ) => $is_print,
|
||
__( 'Sell gift cards at less price?', 'woocommerce-smart-coupons' ) => $sell_sc_at_less_price,
|
||
__( 'Use gift card applied in first subscription order for subsequent renewals until credit reaches zero', 'woocommerce-smart-coupons' ) => $pay_from_credit_of_original_order,
|
||
__( 'Renewal orders should not generate coupons even when they include a product that issues coupons', 'woocommerce-smart-coupons' ) => $stop_recursive_coupon_generation,
|
||
__( 'Allow sending of coupons to others', 'woocommerce-smart-coupons' ) => $is_show_coupon_receiver_form,
|
||
__( 'Allow schedule sending of coupons?', 'woocommerce-smart-coupons' ) => $schedule_store_credit,
|
||
__( 'Combine emails', 'woocommerce-smart-coupons' ) => $combine_emails,
|
||
__( 'Auto generated coupon email', 'woocommerce-smart-coupons' ) => $auto_generated_coupon_email,
|
||
__( 'Combined auto generated coupons email', 'woocommerce-smart-coupons' ) => $combined_email_coupon_enabled,
|
||
__( 'Acknowledgement email', 'woocommerce-smart-coupons' ) => $auto_generated_coupon_email,
|
||
__( 'Enable taxes', 'woocommerce-smart-coupons' ) => $enable_taxes,
|
||
__( 'Prices entered with tax', 'woocommerce-smart-coupons' ) => $price_entered_with_tax_type,
|
||
__( 'Rounding', 'woocommerce-smart-coupons' ) => $round_at_subtotal,
|
||
__( 'Display prices in the shop', 'woocommerce-smart-coupons' ) => $tax_display_shop,
|
||
__( 'Display prices during cart and checkout', 'woocommerce-smart-coupons' ) => $tax_display_cart,
|
||
__( 'Display tax totals', 'woocommerce-smart-coupons' ) => $tax_total_display,
|
||
__( 'Enable the use of coupon codes', 'woocommerce-smart-coupons' ) => $wc_enable_coupons,
|
||
__( 'Calculate coupon discounts sequentially', 'woocommerce-smart-coupons' ) => $calc_discounts_sequentially,
|
||
__( 'Account endpoints > Coupons', 'woocommerce-smart-coupons' ) => $wc_sc_dashboard_endpoint,
|
||
);
|
||
|
||
?>
|
||
<table class="wc_status_table widefat" cellspacing="0" id="wc-smart-coupons-settings">
|
||
<thead>
|
||
<tr>
|
||
<th colspan="3" data-export-label="<?php echo esc_attr( __( 'Smart Coupons related settings', 'woocommerce-smart-coupons' ) ); ?>"><h2><?php esc_html_e( 'Smart Coupons related settings', 'woocommerce-smart-coupons' ); ?><?php echo wp_kses_post( wc_help_tip( __( 'This section shows settings that affects Smart Coupons\' functionalities.', 'woocommerce-smart-coupons' ) ) ); ?></h2></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php
|
||
if ( ! empty( $smart_coupons_settings ) ) {
|
||
foreach ( $smart_coupons_settings as $label => $value ) {
|
||
?>
|
||
<tr>
|
||
<td data-export-label="<?php echo esc_attr( $label ); ?>"><?php echo esc_html( $label ); ?></td>
|
||
<td class="help"></td>
|
||
<td>
|
||
<?php
|
||
echo esc_html( $value );
|
||
?>
|
||
</td>
|
||
</tr>
|
||
<?php
|
||
}
|
||
}
|
||
?>
|
||
</tbody>
|
||
</table>
|
||
<?php
|
||
}
|
||
|
||
/**
|
||
* An alternate(get_option()) way of fetching any option using query.
|
||
*
|
||
* @param string $option_name Option name.
|
||
* @param string $default Default value.
|
||
* @return string|null
|
||
*/
|
||
public function sc_get_option( $option_name = '', $default = '' ) {
|
||
global $wpdb;
|
||
|
||
if ( empty( $option_name ) ) {
|
||
return false;
|
||
}
|
||
return $wpdb->get_var( // phpcs:ignore
|
||
$wpdb->prepare(
|
||
"SELECT IFNULL( option_value, %s )
|
||
FROM {$wpdb->prefix}options
|
||
WHERE option_name = %s",
|
||
$default,
|
||
$option_name
|
||
)
|
||
);
|
||
|
||
}
|
||
|
||
/**
|
||
* Add total SC used in REST API shop order object.
|
||
*
|
||
* @since 5.7.0
|
||
*
|
||
* @param WP_REST_Response $response WP_REST_Response object.
|
||
* @param WC_Order $order WC_Order object.
|
||
* @param WP_REST_Request $request WP_REST_Response object.
|
||
* @return WP_REST_Response
|
||
*/
|
||
public function rest_api_prepare_shop_order_object( $response = null, $order = null, $request = null ) {
|
||
if ( empty( $response ) || empty( $order ) ) {
|
||
return $response;
|
||
}
|
||
|
||
$sc_order_fields = WC_SC_Order_Fields::get_instance();
|
||
|
||
$total_credit_used = $sc_order_fields->get_total_credit_used_in_order( $order );
|
||
|
||
if ( is_object( $response ) && ! empty( $response->data ) && is_array( $response->data ) ) {
|
||
$response->data['store_credit_used'] = round( $total_credit_used, get_option( 'woocommerce_price_num_decimals', 2 ) );
|
||
}
|
||
|
||
return $response;
|
||
}
|
||
|
||
/**
|
||
* Function to get coupon amount considering currency
|
||
*
|
||
* @param WC_Coupon $coupon The coupon object.
|
||
* @param boolean $convert Whether to convert or not.
|
||
* @param WC_Order $order The order object.
|
||
*
|
||
* @throws Exception If $coupon is not an object of WC_Coupon.
|
||
* @return float
|
||
*/
|
||
public function get_amount( $coupon = null, $convert = false, $order = null ) {
|
||
if ( ! is_a( $coupon, 'WC_Coupon' ) ) {
|
||
$error = __( '$coupon is not an object of WC_Coupon', 'woocommerce-smart-coupons' );
|
||
ob_start();
|
||
esc_html_e( '$coupon is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $coupon ) ) ? var_dump( $coupon ) : print_r( gettype( $coupon ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
|
||
$this->log( 'error', print_r( $error, true ) . ' ' . __FILE__ . ' ' . __LINE__ . print_r( "\r\n" . ob_get_clean(), true ) ); // phpcs:ignore
|
||
return floatval( 0 );
|
||
}
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$coupon_amount = ( is_object( $coupon ) && is_callable( array( $coupon, 'get_amount' ) ) ) ? $coupon->get_amount() : 0;
|
||
} else {
|
||
$coupon_amount = ( ! empty( $coupon->amount ) ) ? $coupon->amount : 0;
|
||
}
|
||
return $coupon_amount;
|
||
}
|
||
|
||
/**
|
||
* Maybe convert price read from database to current currency
|
||
*
|
||
* @param integer $price The price to be converted.
|
||
* @param boolean $convert Whether to convert or not.
|
||
* @param WC_Order $order The order object.
|
||
* @return float $price The converted price.
|
||
*/
|
||
public function read_price( $price = 0, $convert = false, $order = null ) {
|
||
if ( true === $convert ) {
|
||
$order_currency = '';
|
||
if ( is_a( $order, 'WC_Order' ) ) {
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$order_currency = ( is_callable( array( $order, 'get_currency' ) ) ) ? $order->get_currency() : ''; // phpcs:ignore
|
||
} else {
|
||
$order_currency = ( is_callable( array( $order, 'get_order_currency' ) ) ) ? $order->get_order_currency() : ''; // phpcs:ignore
|
||
}
|
||
}
|
||
$current_currency = ( ! empty( $order_currency ) ) ? $order_currency : get_woocommerce_currency();
|
||
$base_currency = get_option( 'woocommerce_currency' );
|
||
if ( $base_currency !== $current_currency ) {
|
||
$price = $this->convert_price( $price, $current_currency, $base_currency );
|
||
}
|
||
$price = apply_filters(
|
||
'wc_sc_read_price',
|
||
$price,
|
||
array(
|
||
'source' => $this,
|
||
'currency_conversion' => $convert,
|
||
'order_obj' => $order,
|
||
)
|
||
);
|
||
}
|
||
return $price;
|
||
}
|
||
|
||
/**
|
||
* Maybe convert price to base currency before saving to the database
|
||
*
|
||
* @param integer $price The price to be converted.
|
||
* @param boolean $convert Whether to convert or not.
|
||
* @param WC_Order $order The order object.
|
||
* @return float $price The converted price.
|
||
*/
|
||
public function write_price( $price = 0, $convert = false, $order = null ) {
|
||
if ( true === $convert ) {
|
||
$order_currency = '';
|
||
if ( is_a( $order, 'WC_Order' ) ) {
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$order_currency = ( is_callable( array( $order, 'get_currency' ) ) ) ? $order->get_currency() : ''; // phpcs:ignore
|
||
} else {
|
||
$order_currency = ( is_callable( array( $order, 'get_order_currency' ) ) ) ? $order->get_order_currency() : ''; // phpcs:ignore
|
||
}
|
||
}
|
||
$current_currency = ( ! empty( $order_currency ) ) ? $order_currency : get_woocommerce_currency();
|
||
$base_currency = get_option( 'woocommerce_currency' );
|
||
if ( $base_currency !== $current_currency ) {
|
||
$price = $this->convert_price( $price, $base_currency, $current_currency );
|
||
}
|
||
$price = apply_filters(
|
||
'wc_sc_write_price',
|
||
$price,
|
||
array(
|
||
'source' => $this,
|
||
'currency_conversion' => $convert,
|
||
'order_obj' => $order,
|
||
)
|
||
);
|
||
}
|
||
return $price;
|
||
}
|
||
|
||
/**
|
||
* Get post meta considering currency
|
||
*
|
||
* @param integer $post_id The post id.
|
||
* @param string $meta_key The meta key.
|
||
* @param boolean $single Whether to get single value or not.
|
||
* @param boolean $convert Whether to convert or not.
|
||
* @param WC_Order $order The order object.
|
||
*
|
||
* @throws Exception If Some values not passed for $post_id & $meta_key.
|
||
* @return mixed
|
||
*/
|
||
public function get_post_meta( $post_id = 0, $meta_key = '', $single = false, $convert = false, $order = null ) {
|
||
if ( empty( $post_id ) || empty( $meta_key ) ) {
|
||
$error = __( 'Some values required for $post_id & $meta_key', 'woocommerce-smart-coupons' );
|
||
ob_start();
|
||
esc_html_e( '$post_id is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $post_id ) ) ? var_dump( $post_id ) : print_r( gettype( $post_id ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
esc_html_e( '$meta_key is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $meta_key ) ) ? var_dump( $meta_key ) : print_r( gettype( $meta_key ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
|
||
$this->log( 'error', print_r( $error, true ) . ' ' . __FILE__ . ' ' . __LINE__ . print_r( "\r\n" . ob_get_clean(), true ) ); // phpcs:ignore
|
||
return null;
|
||
}
|
||
$meta_value = '';
|
||
$post_type = ( function_exists( 'get_post_type' ) ) ? get_post_type( $post_id ) : '';
|
||
if ( in_array( $post_type, array( 'product', 'product_variation', 'shop_coupon', 'shop_order' ), true ) ) {
|
||
$object = null;
|
||
$use_getter = false;
|
||
$post_id = absint( $post_id );
|
||
switch ( $post_type ) {
|
||
case 'product':
|
||
case 'product_variation':
|
||
$object = ( function_exists( 'wc_get_product' ) ) ? wc_get_product( $post_id ) : null;
|
||
break;
|
||
case 'shop_coupon':
|
||
$object = new WC_Coupon( $post_id );
|
||
$meta_key_to_props = array(
|
||
'coupon_amount' => 'amount',
|
||
'customer_email' => 'email_restrictions',
|
||
'date_expires' => 'date_expires',
|
||
'discount_type' => 'discount_type',
|
||
'expiry_date' => 'date_expires',
|
||
);
|
||
if ( array_key_exists( $meta_key, $meta_key_to_props ) ) {
|
||
$function = 'get_' . $meta_key_to_props[ $meta_key ];
|
||
if ( $this->is_callable( $object, $function ) ) {
|
||
$use_getter = true;
|
||
}
|
||
}
|
||
break;
|
||
case 'shop_order':
|
||
$object = ( is_object( $order ) && is_a( $order, 'WC_Order' ) ) ? $order : ( function_exists( 'wc_get_order' ) ? wc_get_order( $post_id ) : null );
|
||
$order = $object;
|
||
$meta_key_to_props = array(
|
||
'_order_total' => 'total',
|
||
'_billing_email' => 'billing_email',
|
||
);
|
||
if ( array_key_exists( $meta_key, $meta_key_to_props ) ) {
|
||
$function = 'get_' . $meta_key_to_props[ $meta_key ];
|
||
if ( $this->is_callable( $object, $function ) ) {
|
||
$use_getter = true;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
if ( true === $use_getter ) {
|
||
$meta_value = $object->{$function}();
|
||
} elseif ( $this->is_callable( $object, 'get_meta' ) ) {
|
||
$meta_value = $object->get_meta( $meta_key );
|
||
} else {
|
||
$meta_value = get_post_meta( $post_id, $meta_key, $single );
|
||
}
|
||
if ( in_array( $meta_key, array( 'coupon_amount', 'smart_coupons_contribution', 'wc_sc_max_discount', 'wc_sc_original_amount', 'sc_called_credit_details', '_order_discount', '_order_total' ), true ) ) {
|
||
$order_currency = null;
|
||
if ( ! is_a( $order, 'WC_Order' ) && ! empty( $post_type ) && 'shop_order' === $post_type ) {
|
||
$order = ( ! empty( $post_id ) ) ? wc_get_order( $post_id ) : null;
|
||
}
|
||
if ( is_a( $order, 'WC_Order' ) ) {
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$order_currency = ( is_callable( array( $order, 'get_currency' ) ) ) ? $order->get_currency() : ''; // phpcs:ignore
|
||
} else {
|
||
$order_currency = ( is_callable( array( $order, 'get_order_currency' ) ) ) ? $order->get_order_currency() : ''; // phpcs:ignore
|
||
}
|
||
}
|
||
if ( true === $convert ) {
|
||
$current_currency = ( ! is_null( $order_currency ) ) ? $order_currency : get_woocommerce_currency();
|
||
$base_currency = get_option( 'woocommerce_currency' );
|
||
if ( $base_currency !== $current_currency ) {
|
||
if ( is_scalar( $meta_value ) ) {
|
||
$meta_value = $this->convert_price( $meta_value, $current_currency, $base_currency );
|
||
} elseif ( is_array( $meta_value ) ) {
|
||
array_walk(
|
||
$meta_value,
|
||
array( $this, 'array_convert_price' ),
|
||
array(
|
||
'to_currency' => $current_currency,
|
||
'from_currency' => $base_currency,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
return apply_filters(
|
||
'wc_sc_after_get_post_meta',
|
||
$meta_value,
|
||
array(
|
||
'source' => $this,
|
||
'currency_conversion' => $convert,
|
||
'post_id' => $post_id,
|
||
'meta_key' => $meta_key, // phpcs:ignore
|
||
'order_obj' => $order,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
return $meta_value;
|
||
}
|
||
|
||
/**
|
||
* Update post meta considering currency
|
||
*
|
||
* @param integer $post_id The post id.
|
||
* @param string $meta_key The meta key.
|
||
* @param string $meta_value The meta value.
|
||
* @param boolean $convert Whether to convert or not.
|
||
* @param WC_Order $order The order object.
|
||
*
|
||
* @throws Exception If Some values not passed for $post_id & $meta_key.
|
||
*/
|
||
public function update_post_meta( $post_id = 0, $meta_key = '', $meta_value = '', $convert = false, $order = null ) {
|
||
if ( empty( $post_id ) || empty( $meta_key ) ) {
|
||
$error = __( 'Some values required for $post_id & $meta_key', 'woocommerce-smart-coupons' );
|
||
ob_start();
|
||
esc_html_e( '$post_id is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $post_id ) ) ? var_dump( $post_id ) : print_r( gettype( $post_id ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
esc_html_e( '$meta_key is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $meta_key ) ) ? var_dump( $meta_key ) : print_r( gettype( $meta_key ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
|
||
$this->log( 'error', print_r( $error, true ) . ' ' . __FILE__ . ' ' . __LINE__ . print_r( "\r\n" . ob_get_clean(), true ) ); // phpcs:ignore
|
||
return false;
|
||
}
|
||
$post_type = ( function_exists( 'get_post_type' ) ) ? get_post_type( $post_id ) : '';
|
||
if ( in_array( $meta_key, array( 'coupon_amount', 'smart_coupons_contribution', 'wc_sc_max_discount', 'wc_sc_original_amount', 'sc_called_credit_details', '_order_discount', '_order_total' ), true ) ) {
|
||
$order_currency = null;
|
||
|
||
if ( ! is_a( $order, 'WC_Order' ) && ! empty( $post_type ) && 'shop_order' === $post_type ) {
|
||
$order = ( ! empty( $post_id ) ) ? wc_get_order( $post_id ) : null;
|
||
}
|
||
if ( is_a( $order, 'WC_Order' ) ) {
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$order_currency = ( is_callable( array( $order, 'get_currency' ) ) ) ? $order->get_currency() : ''; // phpcs:ignore
|
||
} else {
|
||
$order_currency = ( is_callable( array( $order, 'get_order_currency' ) ) ) ? $order->get_order_currency() : ''; // phpcs:ignore
|
||
}
|
||
}
|
||
if ( true === $convert ) {
|
||
$current_currency = ( ! is_null( $order_currency ) ) ? $order_currency : get_woocommerce_currency();
|
||
$base_currency = get_option( 'woocommerce_currency' );
|
||
if ( $base_currency !== $current_currency ) {
|
||
if ( is_scalar( $meta_value ) ) {
|
||
$meta_value = $this->convert_price( $meta_value, $base_currency, $current_currency );
|
||
} elseif ( is_array( $meta_value ) ) {
|
||
array_walk(
|
||
$meta_value,
|
||
array( $this, 'array_convert_price' ),
|
||
array(
|
||
'to_currency' => $base_currency,
|
||
'from_currency' => $current_currency,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
$meta_value = apply_filters(
|
||
'wc_sc_before_update_post_meta',
|
||
$meta_value,
|
||
array(
|
||
'source' => $this,
|
||
'currency_conversion' => $convert,
|
||
'post_id' => $post_id,
|
||
'meta_key' => $meta_key, // phpcs:ignore
|
||
'order_obj' => $order,
|
||
)
|
||
);
|
||
}
|
||
if ( in_array( $post_type, array( 'product', 'product_variation', 'shop_coupon', 'shop_order' ), true ) ) {
|
||
$object = null;
|
||
$use_setter = false;
|
||
$post_id = absint( $post_id );
|
||
switch ( $post_type ) {
|
||
case 'product':
|
||
case 'product_variation':
|
||
$object = ( function_exists( 'wc_get_product' ) ) ? wc_get_product( $post_id ) : null;
|
||
break;
|
||
case 'shop_coupon':
|
||
$object = new WC_Coupon( $post_id );
|
||
$meta_key_to_props = array(
|
||
'coupon_amount' => 'amount',
|
||
'customer_email' => 'email_restrictions',
|
||
'date_expires' => 'date_expires',
|
||
'discount_type' => 'discount_type',
|
||
'expiry_date' => 'date_expires',
|
||
);
|
||
if ( array_key_exists( $meta_key, $meta_key_to_props ) ) {
|
||
$function = 'set_' . $meta_key_to_props[ $meta_key ];
|
||
if ( $this->is_callable( $object, $function ) && $this->is_callable( $object, 'save' ) ) {
|
||
$use_setter = true;
|
||
}
|
||
}
|
||
break;
|
||
case 'shop_order':
|
||
$object = ( is_object( $order ) && is_a( $order, 'WC_Order' ) ) ? $order : ( function_exists( 'wc_get_order' ) ? wc_get_order( $post_id ) : null );
|
||
$meta_key_to_props = array(
|
||
'_order_total' => 'total',
|
||
'_billing_email' => 'billing_email',
|
||
);
|
||
if ( array_key_exists( $meta_key, $meta_key_to_props ) ) {
|
||
$function = 'set_' . $meta_key_to_props[ $meta_key ];
|
||
if ( $this->is_callable( $object, $function ) && $this->is_callable( $object, 'save' ) ) {
|
||
$use_setter = true;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
if ( true === $use_setter ) {
|
||
$object->{$function}( $meta_value );
|
||
$object->save();
|
||
} elseif ( $this->is_callable( $object, 'update_meta_data' ) && $this->is_callable( $object, 'save' ) ) {
|
||
$object->update_meta_data( $meta_key, $meta_value );
|
||
$object->save();
|
||
} else {
|
||
update_post_meta( $post_id, $meta_key, $meta_value );
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Wrapper function for deleting post meta
|
||
*
|
||
* @param integer $post_id The post id.
|
||
* @param string $meta_key The meta key to delete.
|
||
* @param string $meta_value The meta value to delete.
|
||
* @param mixed $object The object.
|
||
*
|
||
* @throws Exception If Some values not passed for $post_id & $meta_key.
|
||
*/
|
||
public function delete_post_meta( $post_id = 0, $meta_key = '', $meta_value = '', $object = null ) {
|
||
if ( empty( $post_id ) || empty( $meta_key ) ) {
|
||
$error = __( 'Some values required for $post_id & $meta_key', 'woocommerce-smart-coupons' );
|
||
ob_start();
|
||
esc_html_e( '$post_id is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $post_id ) ) ? var_dump( $post_id ) : print_r( gettype( $post_id ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
esc_html_e( '$meta_key is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $meta_key ) ) ? var_dump( $meta_key ) : print_r( gettype( $meta_key ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
|
||
$this->log( 'error', print_r( $error, true ) . ' ' . __FILE__ . ' ' . __LINE__ . print_r( "\r\n" . ob_get_clean(), true ) ); // phpcs:ignore
|
||
return false;
|
||
}
|
||
if ( is_null( $object ) || ! ( $this->is_callable( $object, 'delete_meta_data' ) && $this->is_callable( $object, 'save' ) ) ) {
|
||
$post_type = ( function_exists( 'get_post_type' ) ) ? get_post_type( $post_id ) : '';
|
||
if ( in_array( $post_type, array( 'product', 'product_variation', 'shop_coupon', 'shop_order' ), true ) ) {
|
||
$post_id = absint( $post_id );
|
||
switch ( $post_type ) {
|
||
case 'product':
|
||
case 'product_variation':
|
||
$object = ( function_exists( 'wc_get_product' ) ) ? wc_get_product( $post_id ) : null;
|
||
break;
|
||
case 'shop_coupon':
|
||
$object = new WC_Coupon( $post_id );
|
||
break;
|
||
case 'shop_order':
|
||
$object = ( is_object( $order ) && is_a( $order, 'WC_Order' ) ) ? $order : ( function_exists( 'wc_get_order' ) ? wc_get_order( $post_id ) : null );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if ( $this->is_callable( $object, 'delete_meta_data' ) && $this->is_callable( $object, 'save' ) ) {
|
||
$object->delete_meta_data( $meta_key );
|
||
$object->save();
|
||
} else {
|
||
delete_post_meta( $post_id, $meta_key );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get value from WooCommerce session
|
||
*
|
||
* @param string $key The key.
|
||
* @param boolean $convert Whether to convert or not.
|
||
*
|
||
* @throws Exception If $key is not passed.
|
||
* @return mixed
|
||
*/
|
||
public function get_session( $key = '', $convert = false ) {
|
||
if ( empty( $key ) ) {
|
||
$error = __( '$key is required', 'woocommerce-smart-coupons' );
|
||
ob_start();
|
||
esc_html_e( '$key is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $key ) ) ? var_dump( $key ) : print_r( gettype( $key ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
|
||
$this->log( 'error', print_r( $error, true ) . ' ' . __FILE__ . ' ' . __LINE__ . print_r( "\r\n" . ob_get_clean(), true ) ); // phpcs:ignore
|
||
return null;
|
||
}
|
||
if ( ! is_callable( 'WC' ) || ! is_object( WC() ) || ! is_object( WC()->session ) || ! is_callable( array( WC()->session, 'get' ) ) ) {
|
||
return null;
|
||
}
|
||
$value = WC()->session->get( $key );
|
||
if ( 'credit_called' !== $key ) {
|
||
return $value;
|
||
}
|
||
if ( true === $convert ) {
|
||
$current_currency = get_woocommerce_currency();
|
||
$base_currency = get_option( 'woocommerce_currency' );
|
||
if ( $base_currency !== $current_currency ) {
|
||
if ( ! empty( $value ) ) {
|
||
if ( is_scalar( $value ) ) {
|
||
$value = $this->convert_price( $value, $current_currency, $base_currency );
|
||
} elseif ( is_array( $value ) ) {
|
||
array_walk(
|
||
$value,
|
||
array( $this, 'array_convert_price' ),
|
||
array(
|
||
'to_currency' => $current_currency,
|
||
'from_currency' => $base_currency,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return apply_filters(
|
||
'wc_sc_after_get_session',
|
||
$value,
|
||
array(
|
||
'source' => $this,
|
||
'currency_conversion' => $convert,
|
||
'key' => $key,
|
||
)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Save a value in WooCommerce session
|
||
*
|
||
* @param string $key The key.
|
||
* @param string $value The value.
|
||
* @param boolean $convert Whether to convert or not.
|
||
*
|
||
* @throws Exception If $key is not passed.
|
||
*/
|
||
public function set_session( $key = '', $value = '', $convert = false ) {
|
||
if ( empty( $key ) ) {
|
||
$error = __( '$key is required', 'woocommerce-smart-coupons' );
|
||
ob_start();
|
||
esc_html_e( '$key is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $key ) ) ? var_dump( $key ) : print_r( gettype( $key ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
|
||
$this->log( 'error', print_r( $error, true ) . ' ' . __FILE__ . ' ' . __LINE__ . print_r( "\r\n" . ob_get_clean(), true ) ); // phpcs:ignore
|
||
return false;
|
||
}
|
||
if ( ! is_callable( 'WC' ) || ! is_object( WC() ) || ! is_object( WC()->session ) || ! is_callable( array( WC()->session, 'set' ) ) ) {
|
||
return;
|
||
}
|
||
if ( 'credit_called' !== $key ) {
|
||
return;
|
||
}
|
||
if ( true === $convert ) {
|
||
$current_currency = get_woocommerce_currency();
|
||
$base_currency = get_option( 'woocommerce_currency' );
|
||
if ( $base_currency !== $current_currency ) {
|
||
if ( ! empty( $value ) ) {
|
||
if ( is_scalar( $value ) ) {
|
||
$value = $this->convert_price( $value, $base_currency, $current_currency );
|
||
} elseif ( is_array( $value ) ) {
|
||
array_walk(
|
||
$value,
|
||
array( $this, 'array_convert_price' ),
|
||
array(
|
||
'to_currency' => $base_currency,
|
||
'from_currency' => $current_currency,
|
||
)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
$value = apply_filters(
|
||
'wc_sc_before_set_session',
|
||
$value,
|
||
array(
|
||
'source' => $this,
|
||
'currency_conversion' => $convert,
|
||
'key' => $key,
|
||
)
|
||
);
|
||
WC()->session->set( $key, $value );
|
||
}
|
||
|
||
/**
|
||
* Get order item meta considering currency
|
||
*
|
||
* @param integer $item_id The order item id.
|
||
* @param string $item_key The order item key.
|
||
* @param boolean $single Whether to get single value or not.
|
||
* @param boolean $convert Whether to convert or not.
|
||
*
|
||
* @throws Exception If Some values not passed for $item_id & $item_key.
|
||
* @return mixed
|
||
*/
|
||
public function get_order_item_meta( $item_id = 0, $item_key = '', $single = false, $convert = false ) {
|
||
if ( empty( $item_id ) || empty( $item_key ) ) {
|
||
$error = __( 'Some values required for $item_id & $item_key', 'woocommerce-smart-coupons' );
|
||
ob_start();
|
||
esc_html_e( '$item_id is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $item_id ) ) ? var_dump( $item_id ) : print_r( gettype( $item_id ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
esc_html_e( '$item_key is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $item_key ) ) ? var_dump( $item_key ) : print_r( gettype( $item_key ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
|
||
$this->log( 'error', print_r( $error, true ) . ' ' . __FILE__ . ' ' . __LINE__ . print_r( "\r\n" . ob_get_clean(), true ) ); // phpcs:ignore
|
||
return null;
|
||
}
|
||
$item_value = wc_get_order_item_meta( $item_id, $item_key, $single );
|
||
if ( in_array( $item_key, array( 'discount', 'discount_amount', 'discount_amount_tax', 'sc_refunded_discount', 'sc_refunded_discount_tax', 'sc_called_credit' ), true ) ) {
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$order_id = ( ! empty( $item_id ) ) ? wc_get_order_id_by_order_item_id( $item_id ) : 0;
|
||
} else {
|
||
$order_id = ( ! empty( $item_id ) ) ? $this->get_order_id_by_order_item_id_wclt30( $item_id ) : 0;
|
||
}
|
||
$order = ( ! empty( $order_id ) ) ? wc_get_order( $order_id ) : null;
|
||
$item = ( is_object( $order ) && is_callable( array( $order, 'get_item' ) ) ) ? $order->get_item( $item_id ) : null;
|
||
if ( true === $convert ) {
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$order_currency = ( is_object( $order ) && is_callable( array( $order, 'get_currency' ) ) ) ? $order->get_currency() : ''; // phpcs:ignore
|
||
} else {
|
||
$order_currency = ( is_object( $order ) && is_callable( array( $order, 'get_order_currency' ) ) ) ? $order->get_order_currency() : ''; // phpcs:ignore
|
||
}
|
||
if ( ! empty( $order_currency ) ) {
|
||
$base_currency = get_option( 'woocommerce_currency' );
|
||
$item_value = $this->convert_price( $item_value, $order_currency, $base_currency );
|
||
}
|
||
}
|
||
return apply_filters(
|
||
'wc_sc_after_get_order_item_meta',
|
||
$item_value,
|
||
array(
|
||
'source' => $this,
|
||
'currency_conversion' => $convert,
|
||
'order_item_obj' => $item,
|
||
'order_item_id' => $item_id,
|
||
'order_item_key' => $item_key,
|
||
)
|
||
);
|
||
}
|
||
return $item_value;
|
||
}
|
||
|
||
/**
|
||
* Add order item meta considering currency
|
||
*
|
||
* @param integer $item_id The order item id.
|
||
* @param string $item_key The order item key.
|
||
* @param string $item_value The order item value.
|
||
* @param boolean $convert Whether to convert or not.
|
||
*
|
||
* @throws Exception If Some values not passed for $item_id & $item_key.
|
||
*/
|
||
public function add_order_item_meta( $item_id = 0, $item_key = '', $item_value = '', $convert = false ) {
|
||
if ( empty( $item_id ) || empty( $item_key ) ) {
|
||
$error = __( 'Some values required for $item_id & $item_key', 'woocommerce-smart-coupons' );
|
||
ob_start();
|
||
esc_html_e( '$item_id is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $item_id ) ) ? var_dump( $item_id ) : print_r( gettype( $item_id ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
esc_html_e( '$item_key is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $item_key ) ) ? var_dump( $item_key ) : print_r( gettype( $item_key ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
|
||
$this->log( 'error', print_r( $error, true ) . ' ' . __FILE__ . ' ' . __LINE__ . print_r( "\r\n" . ob_get_clean(), true ) ); // phpcs:ignore
|
||
return 0;
|
||
}
|
||
if ( in_array( $item_key, array( 'discount', 'discount_amount', 'discount_amount_tax', 'sc_refunded_discount', 'sc_refunded_discount_tax', 'sc_called_credit' ), true ) ) {
|
||
$item_value = $this->get_item_value( $item_id, $item_value, $convert );
|
||
}
|
||
if ( $this->is_wc_gte_30() ) {
|
||
wc_add_order_item_meta( $item_id, $item_key, $item_value );
|
||
} else {
|
||
woocommerce_add_order_item_meta( $item_id, $item_key, $item_value );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Update order item meta considering currency
|
||
*
|
||
* @param integer $item_id The order item id.
|
||
* @param string $item_key The order item key.
|
||
* @param string $item_value The order item value.
|
||
* @param boolean $convert Whether to convert or not.
|
||
*
|
||
* @throws Exception If Some values not passed for $item_id & $item_key.
|
||
*/
|
||
public function update_order_item_meta( $item_id = 0, $item_key = '', $item_value = '', $convert = false ) {
|
||
if ( empty( $item_id ) || empty( $item_key ) ) {
|
||
$error = __( 'Some values required for $item_id & $item_key', 'woocommerce-smart-coupons' );
|
||
ob_start();
|
||
esc_html_e( '$item_id is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $item_id ) ) ? var_dump( $item_id ) : print_r( gettype( $item_id ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
esc_html_e( '$item_key is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $item_key ) ) ? var_dump( $item_key ) : print_r( gettype( $item_key ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
|
||
$this->log( 'error', print_r( $error, true ) . ' ' . __FILE__ . ' ' . __LINE__ . print_r( "\r\n" . ob_get_clean(), true ) ); // phpcs:ignore
|
||
return false;
|
||
}
|
||
if ( in_array( $item_key, array( 'discount', 'discount_amount', 'discount_amount_tax', 'sc_refunded_discount', 'sc_refunded_discount_tax', 'sc_called_credit' ), true ) ) {
|
||
$item_value = $this->get_item_value( $item_id, $item_value, $convert );
|
||
}
|
||
wc_update_order_item_meta( $item_id, $item_key, $item_value );
|
||
}
|
||
|
||
/**
|
||
* Delete order item meta
|
||
*
|
||
* @param integer $item_id The order item id.
|
||
* @param string $item_key The order item key.
|
||
* @param boolean $convert Whether to convert or not.
|
||
*
|
||
* @throws Exception If Some values not passed for $item_id & $item_key.
|
||
*/
|
||
public function delete_order_item_meta( $item_id = 0, $item_key = '', $convert = false ) {
|
||
if ( empty( $item_id ) || empty( $item_key ) ) {
|
||
$error = __( 'Some values required for $item_id & $item_key', 'woocommerce-smart-coupons' );
|
||
ob_start();
|
||
esc_html_e( '$item_id is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $item_id ) ) ? var_dump( $item_id ) : print_r( gettype( $item_id ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
esc_html_e( '$item_key is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $item_key ) ) ? var_dump( $item_key ) : print_r( gettype( $item_key ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
|
||
$this->log( 'error', print_r( $error, true ) . ' ' . __FILE__ . ' ' . __LINE__ . print_r( "\r\n" . ob_get_clean(), true ) ); // phpcs:ignore
|
||
return false;
|
||
}
|
||
if ( in_array( $item_key, array( 'discount', 'discount_amount', 'discount_amount_tax', 'sc_refunded_discount', 'sc_refunded_discount_tax', 'sc_called_credit' ), true ) ) {
|
||
if ( $this->is_wc_gte_30() ) {
|
||
wc_delete_order_item_meta( $item_id, $item_key );
|
||
} else {
|
||
woocommerce_delete_order_item_meta( $item_id, $item_key );
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get order item meta
|
||
*
|
||
* @param WC_Order_item $item The order item object.
|
||
* @param string $item_key The order item meta key.
|
||
* @param boolean $convert Whether to convert or not.
|
||
*
|
||
* @throws Exception If $item is not an object of WC_Order_Item.
|
||
* @return mixed
|
||
*/
|
||
public function get_meta( $item = null, $item_key = '', $convert = false ) {
|
||
if ( ! is_a( $item, 'WC_Order_Item' ) ) {
|
||
$error = __( '$item is not an object of WC_Order_Item', 'woocommerce-smart-coupons' );
|
||
ob_start();
|
||
esc_html_e( '$item is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $item ) ) ? var_dump( $item ) : print_r( gettype( $item ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
|
||
$this->log( 'error', print_r( $error, true ) . ' ' . __FILE__ . ' ' . __LINE__ . print_r( "\r\n" . ob_get_clean(), true ) ); // phpcs:ignore
|
||
return null;
|
||
}
|
||
$item_value = ( is_callable( array( $item, 'get_meta' ) ) ) ? $item->get_meta( $item_key ) : ( ( ! empty( $item[ $item_key ] ) ) ? $item[ $item_key ] : '' );
|
||
if ( in_array( $item_key, array( 'discount', 'discount_amount', 'discount_amount_tax', 'sc_refunded_discount', 'sc_refunded_discount_tax', 'sc_called_credit' ), true ) ) {
|
||
$item_id = ( is_callable( array( $item, 'get_id' ) ) ) ? $item->get_id() : 0;
|
||
if ( true === $convert ) {
|
||
$order = ( is_callable( array( $item, 'get_order' ) ) ) ? $item->get_order() : null;
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$order_currency = ( is_object( $order ) && is_callable( array( $order, 'get_currency' ) ) ) ? $order->get_currency() : ''; // phpcs:ignore
|
||
} else {
|
||
$order_currency = ( is_object( $order ) && is_callable( array( $order, 'get_order_currency' ) ) ) ? $order->get_order_currency() : ''; // phpcs:ignore
|
||
}
|
||
if ( ! empty( $order_currency ) ) {
|
||
$base_currency = get_option( 'woocommerce_currency' );
|
||
$item_value = $this->convert_price( $item_value, $order_currency, $base_currency );
|
||
}
|
||
}
|
||
return apply_filters(
|
||
'wc_sc_after_get_order_item_meta',
|
||
$item_value,
|
||
array(
|
||
'source' => $this,
|
||
'currency_conversion' => $convert,
|
||
'order_item_obj' => $item,
|
||
'order_item_id' => $item_id,
|
||
'order_item_key' => $item_key,
|
||
)
|
||
);
|
||
}
|
||
return $item_value;
|
||
}
|
||
|
||
/**
|
||
* Update order item meta considering currency
|
||
*
|
||
* @param WC_Order_item $item The order item object.
|
||
* @param string $item_key The order item meta key.
|
||
* @param string $item_value The order item value.
|
||
* @param boolean $convert Whether to convert or not.
|
||
*
|
||
* @throws Exception If $item is not an object of WC_Order_Item.
|
||
*/
|
||
public function update_meta_data( &$item = null, $item_key = '', $item_value = '', $convert = false ) {
|
||
if ( ! is_a( $item, 'WC_Order_Item' ) ) {
|
||
$error = __( '$item is not an object of WC_Order_Item', 'woocommerce-smart-coupons' );
|
||
ob_start();
|
||
esc_html_e( '$item is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $item ) ) ? var_dump( $item ) : print_r( gettype( $item ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
|
||
$this->log( 'error', print_r( $error, true ) . ' ' . __FILE__ . ' ' . __LINE__ . print_r( "\r\n" . ob_get_clean(), true ) ); // phpcs:ignore
|
||
return false;
|
||
}
|
||
if ( in_array( $item_key, array( 'discount', 'discount_amount', 'discount_amount_tax', 'sc_refunded_discount', 'sc_refunded_discount_tax', 'sc_called_credit' ), true ) ) {
|
||
$item_id = ( is_callable( array( $item, 'get_id' ) ) ) ? $item->get_id() : 0;
|
||
$item_value = $this->get_item_value( $item_id, $item_value, $convert );
|
||
if ( is_callable( array( $item, 'update_meta_data' ) ) ) {
|
||
$item->update_meta_data( $item_key, $item_value );
|
||
} else {
|
||
$item[ $item_key ] = $item_value;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check & convert price
|
||
*
|
||
* @since 6.0.0
|
||
*
|
||
* @param float $price The price need to be converted.
|
||
* @param string $to_currency The price will be converted to this currency.
|
||
* @param string $from_currency The price will be converted from this currency.
|
||
* @return float
|
||
*/
|
||
public function convert_price( $price = 0, $to_currency = null, $from_currency = null ) {
|
||
if ( ! class_exists( 'WC_SC_Aelia_CS_Compatibility' ) ) {
|
||
include_once 'compat/class-wc-sc-aelia-cs-compatibility.php';
|
||
}
|
||
return WC_SC_Aelia_CS_Compatibility::get_instance()->convert_price( $price, $to_currency, $from_currency );
|
||
}
|
||
|
||
/**
|
||
* Callback function for array_walk to apply convert price on each element of array
|
||
*
|
||
* @param mixed $value The array element.
|
||
* @param mixed $key The array key.
|
||
* @param array $args The additional arguments.
|
||
*/
|
||
public function array_convert_price( &$value = null, $key = null, $args = null ) {
|
||
if ( ! is_null( $value ) && ! is_null( $key ) && ! is_null( $args ) ) {
|
||
$to_currency = ( ! empty( $args['to_currency'] ) ) ? $args['to_currency'] : '';
|
||
$from_currency = ( ! empty( $args['from_currency'] ) ) ? $args['from_currency'] : '';
|
||
if ( ! empty( $to_currency ) && ! empty( $from_currency ) ) {
|
||
$value = $this->convert_price( $value, $to_currency, $from_currency );
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get item value for saving/updating in DB considering currency
|
||
*
|
||
* @param integer $item_id The order item id.
|
||
* @param string $item_value The item value.
|
||
* @param boolean $convert Whether to convert or not.
|
||
*
|
||
* @throws Exception If $item is not passed.
|
||
* @return mixed
|
||
*/
|
||
public function get_item_value( $item_id = 0, $item_value = '', $convert = false ) {
|
||
if ( empty( $item_id ) ) {
|
||
$error = __( '$item_id is required', 'woocommerce-smart-coupons' );
|
||
ob_start();
|
||
esc_html_e( '$item_id is: ', 'woocommerce-smart-coupons' ) . ( is_scalar( $item_id ) ) ? var_dump( $item_id ) : print_r( gettype( $item_id ) ) . print_r( "\r\n" ); // phpcs:ignore
|
||
debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore
|
||
$this->log( 'error', print_r( $error, true ) . ' ' . __FILE__ . ' ' . __LINE__ . print_r( "\r\n" . ob_get_clean(), true ) ); // phpcs:ignore
|
||
return null;
|
||
}
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$order_id = ( ! empty( $item_id ) ) ? wc_get_order_id_by_order_item_id( $item_id ) : 0;
|
||
} else {
|
||
$order_id = ( ! empty( $item_id ) ) ? $this->get_order_id_by_order_item_id_wclt30( $item_id ) : 0;
|
||
}
|
||
$order = ( ! empty( $order_id ) ) ? wc_get_order( $order_id ) : null;
|
||
if ( true === $convert ) {
|
||
if ( $this->is_wc_gte_30() ) {
|
||
$order_currency = ( is_object( $order ) && is_callable( array( $order, 'get_currency' ) ) ) ? $order->get_currency() : ''; // phpcs:ignore
|
||
} else {
|
||
$order_currency = ( is_object( $order ) && is_callable( array( $order, 'get_order_currency' ) ) ) ? $order->get_order_currency() : ''; // phpcs:ignore
|
||
}
|
||
if ( ! empty( $order_currency ) ) {
|
||
$base_currency = get_option( 'woocommerce_currency' );
|
||
if ( $base_currency !== $order_currency ) {
|
||
$item_value = $this->convert_price( $item_value, $base_currency, $order_currency );
|
||
}
|
||
}
|
||
}
|
||
return apply_filters(
|
||
'wc_sc_before_update_order_item_meta',
|
||
$item_value,
|
||
array(
|
||
'source' => $this,
|
||
'currency_conversion' => $convert,
|
||
'order_obj' => $order,
|
||
'order_item_id' => $item_id,
|
||
)
|
||
);
|
||
|
||
}
|
||
|
||
/**
|
||
* Get order id by order item id for WooCommerce version lower than 3.0.0
|
||
*
|
||
* @param integer $item_id The order item id.
|
||
* @return mixed
|
||
*/
|
||
public function get_order_id_by_order_item_id_wclt30( $item_id = 0 ) {
|
||
global $wpdb;
|
||
return $wpdb->get_var( // phpcs:ignore
|
||
$wpdb->prepare(
|
||
"SELECT order_id
|
||
FROM {$wpdb->prefix}woocommerce_order_items
|
||
WHERE order_item_id = %d",
|
||
absint( $item_id )
|
||
)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Convert a date string to a WC_DateTime.
|
||
*
|
||
* Wrapper function to give support for store running WooCommerce 3.0.0.
|
||
*
|
||
* Credit: WooCommerce
|
||
*
|
||
* @since 6.3.0
|
||
* @param string $time_string Time string.
|
||
* @return WC_DateTime
|
||
*/
|
||
public function wc_string_to_datetime( $time_string ) {
|
||
|
||
if ( function_exists( 'wc_string_to_datetime' ) ) {
|
||
return wc_string_to_datetime( $time_string );
|
||
}
|
||
|
||
// Strings are defined in local WP timezone. Convert to UTC.
|
||
if ( 1 === preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|((-|\+)\d{2}:\d{2}))$/', $time_string, $date_bits ) ) {
|
||
$offset = ! empty( $date_bits[7] ) ? iso8601_timezone_to_offset( $date_bits[7] ) : $this->wc_timezone_offset();
|
||
$timestamp = gmmktime( $date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1] ) - $offset;
|
||
} else {
|
||
$timestamp = wc_string_to_timestamp( get_gmt_from_date( gmdate( 'Y-m-d H:i:s', wc_string_to_timestamp( $time_string ) ) ) );
|
||
}
|
||
$datetime = new WC_DateTime( "@{$timestamp}", new DateTimeZone( 'UTC' ) );
|
||
|
||
// Set local timezone or offset.
|
||
if ( get_option( 'timezone_string' ) ) {
|
||
$datetime->setTimezone( new DateTimeZone( wc_timezone_string() ) );
|
||
} else {
|
||
$datetime->set_utc_offset( $this->wc_timezone_offset() );
|
||
}
|
||
|
||
return $datetime;
|
||
}
|
||
|
||
/**
|
||
* Get timezone offset in seconds.
|
||
*
|
||
* Wrapper function for giving support to lower version of WooCommerce
|
||
*
|
||
* Credit: WooCommerce
|
||
*
|
||
* @since 6.3.0
|
||
* @return float
|
||
*/
|
||
public function wc_timezone_offset() {
|
||
|
||
if ( function_exists( 'wc_timezone_offset' ) ) {
|
||
return wc_timezone_offset();
|
||
}
|
||
|
||
$timezone = get_option( 'timezone_string' );
|
||
|
||
if ( $timezone ) {
|
||
$timezone_object = new DateTimeZone( $timezone );
|
||
return $timezone_object->getOffset( new DateTime( 'now' ) );
|
||
} else {
|
||
return floatval( get_option( 'gmt_offset', 0 ) ) * HOUR_IN_SECONDS;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get timestamp from date string
|
||
*
|
||
* @param string $date_string The date in string format.
|
||
* @return int
|
||
*/
|
||
public function wc_string_to_datetime_to_timestamp( $date_string = '' ) {
|
||
$timestamp = null;
|
||
if ( ! empty( $date_string ) ) {
|
||
$datetime = $this->wc_string_to_datetime( $date_string );
|
||
$timestamp = ( is_object( $datetime ) && is_callable( array( $datetime, 'getTimestamp' ) ) ) ? $datetime->getTimestamp() : null;
|
||
}
|
||
return $timestamp;
|
||
}
|
||
|
||
/**
|
||
* Maybe convert to correct value for meta 'date_expires'
|
||
*
|
||
* @param mixed $date_expires The current date_expires value.
|
||
* @return mixed
|
||
*/
|
||
public function get_date_expires_value( $date_expires = null ) {
|
||
$date_expires = intval( $date_expires );
|
||
$date_expires = ( ! empty( $date_expires ) ) ? $date_expires : null;
|
||
return $date_expires;
|
||
}
|
||
|
||
/**
|
||
* Converts a string (e.g. 'yes' or 'no') to a bool.
|
||
*
|
||
* Credit: WooCommerce
|
||
*
|
||
* @since 7.2.0
|
||
* @param string|bool $string String to convert. If a bool is passed it will be returned as-is.
|
||
* @return bool
|
||
*/
|
||
public function wc_string_to_bool( $string ) {
|
||
|
||
if ( function_exists( 'wc_string_to_bool' ) ) {
|
||
return wc_string_to_bool( $string );
|
||
}
|
||
|
||
return is_bool( $string ) ? $string : ( 'yes' === strtolower( $string ) || 1 === $string || 'true' === strtolower( $string ) || '1' === $string );
|
||
}
|
||
|
||
/**
|
||
* Converts a bool to a 'yes' or 'no'.
|
||
*
|
||
* Credit: WooCommerce
|
||
*
|
||
* @since 7.2.0
|
||
* @param bool|string $bool Bool to convert. If a string is passed it will first be converted to a bool.
|
||
* @return string
|
||
*/
|
||
public function wc_bool_to_string( $bool ) {
|
||
|
||
if ( function_exists( 'wc_bool_to_string' ) ) {
|
||
return wc_bool_to_string( $bool );
|
||
}
|
||
|
||
if ( ! is_bool( $bool ) ) {
|
||
$bool = $this->wc_string_to_bool( $bool );
|
||
}
|
||
return true === $bool ? 'yes' : 'no';
|
||
}
|
||
|
||
/**
|
||
* Compatible function for mb_detect_encoding.
|
||
*
|
||
* (c) Fabien Potencier <fabien@symfony.com>
|
||
*
|
||
* @author Nicolas Grekas <p@tchwork.com>
|
||
*
|
||
* @param string $string The string to be checked.
|
||
* @param mixed $encodings List of encoding.
|
||
* @param boolean $strict Strict checking or not.
|
||
* @return mixed
|
||
*/
|
||
public function mb_detect_encoding( $string, $encodings = null, $strict = false ) {
|
||
|
||
if ( function_exists( 'mb_detect_encoding' ) ) {
|
||
return mb_detect_encoding( $string, $encodings, $strict );
|
||
}
|
||
|
||
if ( null === $encodings ) {
|
||
$encodings = array( 'ASCII', 'UTF-8' );
|
||
} else {
|
||
if ( ! is_array( $encodings ) ) {
|
||
$encodings = array_map( 'trim', explode( ',', $encodings ) );
|
||
}
|
||
$encodings = array_map( 'strtoupper', $encodings );
|
||
}
|
||
|
||
foreach ( $encodings as $enc ) {
|
||
switch ( $enc ) {
|
||
case 'ASCII':
|
||
if ( ! preg_match( '/[\x80-\xFF]/', $string ) ) {
|
||
return $enc;
|
||
}
|
||
break;
|
||
|
||
case 'UTF8':
|
||
case 'UTF-8':
|
||
if ( preg_match( '//u', $string ) ) {
|
||
return 'UTF-8';
|
||
}
|
||
break;
|
||
|
||
default:
|
||
if ( 0 === strncmp( $enc, 'ISO-8859-', 9 ) ) {
|
||
return $enc;
|
||
}
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Check if a method is callable w.r.t. given object or not
|
||
*
|
||
* @param mixed $object The object.
|
||
* @param string $method The method name.
|
||
* @return boolean
|
||
*/
|
||
public function is_callable( $object = null, $method = '' ) {
|
||
if ( empty( $object ) || empty( $method ) ) {
|
||
return false;
|
||
}
|
||
$type = gettype( $object );
|
||
if ( ! in_array( $type, array( 'string', 'object' ), true ) ) {
|
||
return false;
|
||
}
|
||
if ( 'string' === $type && ! class_exists( $object ) ) {
|
||
return false;
|
||
}
|
||
return is_callable( array( $object, $method ) );
|
||
}
|
||
|
||
/**
|
||
* Function to declare WooCommerce HPOS related compatibility status
|
||
*/
|
||
public function hpos_compat_declaration() {
|
||
if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) {
|
||
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', 'woocommerce-smart-coupons/woocommerce-smart-coupons.php', false );
|
||
}
|
||
}
|
||
|
||
}//end class
|
||
|
||
} // End class exists check
|