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' );
}
?>
'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 ], '' . $discount_text . '', __( 'Use code', 'woocommerce-smart-coupons' ), '' . $coupon_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' ), '' . $coupon_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' ), '' . $coupon_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' ), '' . $coupon_code . '' ), '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,
)
);
?>
' . $file . '' ) . ' ' . __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' ), '' . $file . '' ) . ' ' . __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'];
?>
' . esc_html__( 'Important', 'woocommerce-smart-coupons' ) . ': ' . esc_html( $plugin_name ) . ' ' . esc_html__( 'is active but it will only work with WooCommerce 3.0.0+.', 'woocommerce-smart-coupons' ) . ' ' . esc_html__( 'Please update WooCommerce to the latest version', 'woocommerce-smart-coupons' ) . '.'; ?>
* * @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