JezK
Edit File: class-emails.php
<?php /** * Price tracker emails class. * * @package woodmart */ namespace XTS\Modules\Price_Tracker; use WC_Coupon; use WC_Product; /** * Price tracker emails class. */ class Emails { /** * Instance of DB_Storage class. * * @var DB_Storage $db_storage - Instance of DB_Storage class. */ private $db_storage; /** * Init. */ public function __construct() { if ( ! woodmart_get_opt( 'price_tracker_enabled' ) || ! woodmart_woocommerce_installed() ) { return; } $this->db_storage = DB_Storage::get_instance(); add_action( 'init', array( $this, 'unsubscribe_user' ) ); add_filter( 'woocommerce_email_classes', array( $this, 'register_email' ) ); add_action( 'woocommerce_init', array( $this, 'load_wc_mailer' ) ); add_filter( 'woocommerce_prepare_email_for_preview', array( $this, 'prepare_email_for_preview' ) ); add_action( 'woodmart_price_tracker_cron', array( $this, 'send_price_tracker_email' ) ); add_action( 'init', array( $this, 'schedule_cron_event' ) ); } /** * Schedule cron event on init hook. * * @return void */ public function schedule_cron_event() { if ( ! wp_next_scheduled( 'woodmart_price_tracker_cron' ) ) { wp_schedule_event( time(), apply_filters( 'woodmart_schedule_send_price_tracker_email', 'hourly' ), 'woodmart_price_tracker_cron' ); } } /** * Unsubscribe after the user has followed the link from email. */ public function unsubscribe_user() { if ( ! isset( $_GET['token'] ) || ! isset( $_GET['email'] ) || ! isset( $_GET['action'] ) || 'woodmart_price_tracker_unsubscribe' !== $_GET['action'] ) { //phpcs:ignore return; } $redirect = apply_filters( 'woodmart_price_tracker_after_unsubscribe_redirect', remove_query_arg( array( 'token', 'email', 'action' ) ) ); $token = woodmart_clean( $_GET['token'] ); //phpcs:ignore. $user_email = isset( $_GET['email'] ) ? sanitize_email( wp_unslash( $_GET['email'] ) ) : ''; //phpcs:ignore. $result = false; if ( ! empty( $user_email ) && ! empty( $token ) && $this->validate_unsubscribe_token( $user_email, $token ) ) { $result = $this->db_storage->unsubscribe_by_email( $user_email ); } if ( $result ) { wc_add_notice( esc_html__( 'You’ve been unsubscribed from price tracker emails for this product', 'woodmart' ), 'success' ); } else { wc_add_notice( esc_html__( 'Failed to unsubscribe from price tracker emails for this product', 'woodmart' ), 'error' ); } wp_safe_redirect( $redirect ); exit(); } /** * Validate the unsubscribe token for an email. * Finds the subscription record by token and email. * * @param string $email The email to validate. * @param string $token The token to validate. * * @return bool True if the token is valid, false otherwise. */ public function validate_unsubscribe_token( $email, $token ) { if ( empty( $token ) || empty( $email ) ) { return false; } return $this->db_storage->check_subscription_token_exists( $email, $token ); } /** * List of registered emails. * * @param array $emails List of registered emails. * * @return array */ public function register_email( $emails ) { $emails['XTS_Email_Price_Tracker'] = include WOODMART_THEMEROOT . '/inc/integrations/woocommerce/modules/price-tracker/emails/class-xts-email-price-tracker.php'; $emails['XTS_Email_Price_Tracker_Subscribe'] = include WOODMART_THEMEROOT . '/inc/integrations/woocommerce/modules/price-tracker/emails/class-xts-email-price-tracker-subscribe.php'; return $emails; } /** * Load woocommerce mailer. */ public function load_wc_mailer() { add_action( 'woodmart_send_price_tracker', array( 'WC_Emails', 'send_transactional_email' ), 10, 4 ); add_action( 'woodmart_send_price_tracker_subscribe', array( 'WC_Emails', 'send_transactional_email' ), 10, 4 ); } /** * Prepare email for preview. * * @param object $preview_email Email object. */ public function prepare_email_for_preview( $preview_email ) { $preview_email_class = get_class( $preview_email ); $dummy_product = $this->get_dummy_product(); if ( in_array( $preview_email_class, array( 'XTS_Email_Price_Tracker', 'XTS_Email_Price_Tracker_Subscribe' ), true ) ) { $preview_email->recipient = 'user_preview@example.com'; $preview_email->user_name = esc_html__( 'User Preview', 'woodmart' ); } if ( 'XTS_Email_Price_Tracker' === $preview_email_class ) { $preview_email->set_object( $this->get_dummy_data() ); $preview_email->dummy_product = $dummy_product; } if ( 'XTS_Email_Price_Tracker_Subscribe' === $preview_email_class ) { $preview_email->set_object( $dummy_product ); $preview_email->product_price_html = wc_price( 25 ); } return $preview_email; } /** * Send priced tracker cart email. * * @codeCoverageIgnore */ public function send_price_tracker_email() { $emails_limit = apply_filters( 'woodmart_send_price_tracker_email_limited', 20 ); $product_limit = apply_filters( 'woodmart_send_price_tracker_email_product_limited', 10 ); $subscriptions_to_send = $this->db_storage->get_subscriptions_to_send( $emails_limit, $product_limit ); $subscriptions_to_send = $this->group_subscriptions_by_language( $subscriptions_to_send ); if ( ! $subscriptions_to_send ) { return; } foreach ( $subscriptions_to_send as $email => $subscriptions ) { foreach ( $subscriptions as $email_language => $email_products ) { do_action( 'woodmart_send_price_tracker', $email, $email_products, $email_language ); $this->db_storage->update_subscriptions_sent_status( array_keys( $email_products ) ); } } } /** * Retrieves subscription records from the database and groups them by the language they were sent in. * If WPML is enabled, emails will be grouped depending on the data in the email_language column, otherwise this column will be ignored and all emails will be grouped with the default key. * When WPML is enabled, this method converts the product id to the desired language. * When Multicurrency is enabled, this method converts product prices to the required currency. * * @param array $subscriptions_groped List of subscriptions grouped by user email. * * @return array */ public function group_subscriptions_by_language( $subscriptions_groped ) { global $woocommerce_wpml; if ( empty( $subscriptions_groped ) ) { return array(); } $grouped = array(); foreach ( $subscriptions_groped as $email => $subscriptions ) { foreach ( $subscriptions as $subscription ) { $product = wc_get_product( $subscription->variation_id ? $subscription->variation_id : $subscription->product_id ); $product_price = $product->get_price(); $desired_price = floatval( $subscription->desired_price ); if ( ! $product instanceof WC_Product || ! $product->is_in_stock() || $product_price > $subscription->product_price || ( ! empty( $desired_price ) && $product_price > $desired_price ) ) { continue; } $lang = 'default'; $email_currency = 'default'; if ( defined( 'ICL_SITEPRESS_VERSION' ) ) { $lang = ! empty( $subscription->email_language ) ? $subscription->email_language : 'default'; } if ( defined( 'WCML_VERSION' ) ) { $email_currency = ! empty( $subscription->email_currency ) ? $subscription->email_currency : 'default'; } if ( defined( 'ICL_SITEPRESS_VERSION' ) && 'default' !== $lang ) { $subscription->product_id = apply_filters( 'wpml_object_id', $subscription->product_id, 'product', true, $lang ); $subscription->variation_id = apply_filters( 'wpml_object_id', $subscription->variation_id, 'product', true, $lang ); } if ( defined( 'WCML_VERSION' ) && isset( $woocommerce_wpml ) && is_object( $woocommerce_wpml->multi_currency ) ) { $default_currency = $woocommerce_wpml->multi_currency->get_default_currency(); if ( 'default' !== $email_currency && 'default' !== $email_currency && $default_currency !== $email_currency ) { $subscription->product_price = $woocommerce_wpml->multi_currency->prices->convert_price_amount_by_currencies( $subscription->product_price, $default_currency, $email_currency ); $subscription->product_new_price = $woocommerce_wpml->multi_currency->prices->convert_price_amount_by_currencies( $subscription->product_new_price, $default_currency, $email_currency ); $subscription->desired_price = $woocommerce_wpml->multi_currency->prices->convert_price_amount_by_currencies( $subscription->desired_price, $default_currency, $email_currency ); } } $grouped[ $email ][ $lang ][ $subscription->list_id ] = $subscription; } } return $grouped; } /** * Get a dummy data. * * @return array */ private function get_dummy_data() { $dummy_data = array( 'list_id' => '1', 'user_id' => '1', 'user_email' => 'user_preview@example.com', 'product_id' => '123', 'variation_id' => '123', 'product_price' => '123', 'product_new_price' => '100', 'subscribe_status' => 'discounted', 'is_sent' => '', 'email_language' => '', 'email_currency' => '', 'unsubscribe_token' => '', 'created_date' => '', 'created_date_gmt' => '', ); return array( (object) $dummy_data ); } /** * Get a dummy product. * * @return WC_Product */ private function get_dummy_product() { $product = new WC_Product(); $product->set_name( __( 'Dummy Product', 'woodmart' ) ); $product->set_price( 25 ); return $product; } } new Emails();