mirror of
https://github.com/pronamic/woocommerce-subscriptions.git
synced 2025-10-18 07:12:55 +00:00
304 lines
9.7 KiB
PHP
304 lines
9.7 KiB
PHP
<?php
|
|
/**
|
|
* Subscriptions Email Preview Class
|
|
*/
|
|
class WC_Subscriptions_Email_Preview {
|
|
|
|
/**
|
|
* The email being previewed
|
|
*
|
|
* @var string
|
|
*/
|
|
private $email_type;
|
|
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
public function __construct() {
|
|
add_filter( 'woocommerce_prepare_email_for_preview', [ $this, 'prepare_email_for_preview' ] );
|
|
}
|
|
|
|
/**
|
|
* Prepare subscription email dummy data for preview.
|
|
*
|
|
* @param WC_Email $email The email object.
|
|
*
|
|
* @return WC_Email
|
|
*/
|
|
public function prepare_email_for_preview( $email ) {
|
|
$this->email_type = get_class( $email );
|
|
|
|
if ( ! $this->is_subscription_email() ) {
|
|
return $email;
|
|
}
|
|
|
|
$this->set_up_filters();
|
|
|
|
switch ( $this->email_type ) {
|
|
case 'WCS_Email_New_Switch_Order':
|
|
case 'WCS_Email_Completed_Switch_Order':
|
|
$email->subscriptions = [ $this->get_dummy_subscription() ];
|
|
break;
|
|
case 'WCS_Email_Cancelled_Subscription':
|
|
case 'WCS_Email_Expired_Subscription':
|
|
case 'WCS_Email_On_Hold_Subscription':
|
|
case 'WCS_Email_Customer_Notification_Auto_Trial_Expiration':
|
|
case 'WCS_Email_Customer_Notification_Manual_Trial_Expiration':
|
|
case 'WCS_Email_Customer_Notification_Subscription_Expiration':
|
|
case 'WCS_Email_Customer_Notification_Manual_Renewal':
|
|
case 'WCS_Email_Customer_Notification_Auto_Renewal':
|
|
$email->set_object( $this->get_dummy_subscription() );
|
|
break;
|
|
case 'WCS_Email_Customer_Payment_Retry':
|
|
case 'WCS_Email_Payment_Retry':
|
|
$email->retry = $this->get_dummy_retry( $email->object );
|
|
break;
|
|
}
|
|
|
|
$this->add_placeholders( $email );
|
|
|
|
add_filter( 'woocommerce_mail_content', [ $this, 'clean_up_filters' ] );
|
|
|
|
return $email;
|
|
}
|
|
|
|
/**
|
|
* Get a dummy subscription for use in preview emails.
|
|
*
|
|
* @return WC_Subscription
|
|
*/
|
|
private function get_dummy_subscription() {
|
|
$subscription = new WC_Subscription();
|
|
$product = $this->get_dummy_product();
|
|
|
|
$subscription->add_product( $product, 2 );
|
|
$subscription->set_id( 12346 );
|
|
$subscription->set_customer_id( 1 );
|
|
$subscription->set_date_created( gmdate( 'Y-m-d H:i:s', strtotime( '-1 month' ) ) );
|
|
$subscription->set_currency( 'USD' );
|
|
$subscription->set_total( 100 );
|
|
$subscription->set_billing_period( 'month' );
|
|
$subscription->set_billing_interval( 1 );
|
|
$subscription->set_start_date( gmdate( 'Y-m-d H:i:s', strtotime( '-1 month' ) ) );
|
|
$subscription->set_trial_end_date( gmdate( 'Y-m-d H:i:s', strtotime( '+1 week' ) ) );
|
|
$subscription->set_next_payment_date( gmdate( 'Y-m-d H:i:s', strtotime( '+1 week' ) ) );
|
|
$subscription->set_end_date( gmdate( 'Y-m-d H:i:s', strtotime( '+1 month' ) ) );
|
|
|
|
$address = self::get_dummy_address();
|
|
|
|
$subscription->set_billing_address( $address );
|
|
$subscription->set_shipping_address( $address );
|
|
|
|
/**
|
|
* Filter the dummy subscription object used in email previews.
|
|
*
|
|
* @param WC_Subscription $subscription The dummy subscription object.
|
|
* @param string $email_type The email type being previewed.
|
|
*/
|
|
return apply_filters( 'woocommerce_subscriptions_email_preview_dummy_subscription', $subscription, $this->email_type );
|
|
}
|
|
|
|
/**
|
|
* Get a dummy product for use when previewing subscription emails.
|
|
*
|
|
* @return WC_Product
|
|
*/
|
|
private function get_dummy_product() {
|
|
$product = new WC_Product();
|
|
$product->set_name( 'Dummy Subscription' );
|
|
$product->set_price( 25 );
|
|
|
|
/**
|
|
* Filter the dummy subscription product object used in email previews.
|
|
*
|
|
* @param WC_Product $product The dummy product object.
|
|
* @param string $email_type The email type being previewed.
|
|
*/
|
|
return apply_filters( 'woocommerce_subscriptions_email_preview_dummy_product', $product, $this->email_type );
|
|
}
|
|
|
|
/**
|
|
* Get a dummy address used when previewing subscription emails.
|
|
*
|
|
* @return array
|
|
*/
|
|
private function get_dummy_address() {
|
|
$address = [
|
|
'first_name' => 'John',
|
|
'last_name' => 'Doe',
|
|
'company' => 'Company',
|
|
'email' => 'john@company.com',
|
|
'phone' => '555-555-5555',
|
|
'address_1' => '123 Fake Street',
|
|
'city' => 'Faketown',
|
|
'postcode' => '12345',
|
|
'country' => 'US',
|
|
'state' => 'CA',
|
|
];
|
|
|
|
/**
|
|
* Filter the dummy address used in email previews.
|
|
*
|
|
* @param array $address The dummy address.
|
|
* @param string $email_type The email type being previewed.
|
|
*/
|
|
return apply_filters( 'woocommerce_subscriptions_email_preview_dummy_address', $address, $this->email_type );
|
|
}
|
|
|
|
/**
|
|
* Creates a dummy retry for use when previewing failed subscription payment retry emails.
|
|
*
|
|
* @param WC_Order $order The order object to create a dummy retry for.
|
|
* @return WCS_Retry The dummy retry object.
|
|
*/
|
|
private function get_dummy_retry( $order ) {
|
|
|
|
if ( ! class_exists( 'WCS_Retry_Manager' ) ) {
|
|
return null;
|
|
}
|
|
|
|
$order_id = is_a( $order, 'WC_Order' ) ? $order->get_id() : 12345;
|
|
$retry_rule = WCS_Retry_Manager::rules()->get_rule( 1, $order_id );
|
|
|
|
if ( is_a( $retry_rule, 'WCS_Retry_Rule' ) ) {
|
|
$interval = $retry_rule->get_retry_interval();
|
|
$raw_retry_rule = $retry_rule->get_raw_data();
|
|
} else {
|
|
// If the retry rule is not found, use a default interval of 12 hours and an empty raw rule.
|
|
$interval = 12 * HOUR_IN_SECONDS;
|
|
$raw_retry_rule = [];
|
|
}
|
|
|
|
return new WCS_Retry(
|
|
[
|
|
'status' => 'pending',
|
|
'order_id' => $order_id,
|
|
'date_gmt' => gmdate( 'Y-m-d H:i:s', time() + $interval ),
|
|
'rule_raw' => $raw_retry_rule,
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if the email being previewed is a subscription email.
|
|
*
|
|
* Subscription emails include:
|
|
* - WC_Subscriptions_Email::$email_classes - core subscription emails.
|
|
* - WC_Subscriptions_Email_Notifications::$email_classes - subscription notification emails (pre-renewal emails).
|
|
* - WCS_Email_Customer_Payment_Retry - customer payment retry emails.
|
|
* - WCS_Email_Payment_Retry - admin payment retry emails.
|
|
*
|
|
* @return bool Whether the email being previewed is a subscription email.
|
|
*/
|
|
private function is_subscription_email() {
|
|
return isset( WC_Subscriptions_Email::$email_classes[ $this->email_type ] )
|
|
|| isset( WC_Subscriptions_Email_Notifications::$email_classes[ $this->email_type ] )
|
|
|| in_array( $this->email_type, [ 'WCS_Email_Customer_Payment_Retry', 'WCS_Email_Payment_Retry' ], true );
|
|
}
|
|
|
|
/**
|
|
* Set up filters for previewing emails.
|
|
*/
|
|
private function set_up_filters() {
|
|
// Filter the last order date created for a subscription to be displayed in the Cancelled Subscription email.
|
|
add_filter( 'woocommerce_subscription_get_last_order_date_created_date', [ $this, 'mock_last_order_date_created' ], 10, 2 );
|
|
// For the purpose of previewing an email, force the subscription to be early renewable if the feature is enabled.
|
|
add_filter( 'woocommerce_subscriptions_can_user_renew_early', [ $this, 'allow_early_renewals_during_preview' ], 10, 3 );
|
|
}
|
|
|
|
/**
|
|
* Clean up filters at the end of previewing emails.
|
|
*
|
|
* @param string $preview_content The email content.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function clean_up_filters( $preview_content ) {
|
|
remove_filter( 'woocommerce_subscription_get_last_order_date_created_date', [ $this, 'mock_last_order_date_created' ] );
|
|
remove_filter( 'woocommerce_subscriptions_can_user_renew_early', [ $this, 'allow_early_renewals_during_preview' ] );
|
|
|
|
return $preview_content;
|
|
|
|
}
|
|
|
|
/**
|
|
* Mock the last order date created for a subscription to the current date.
|
|
*
|
|
* @param string $date The date.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function mock_last_order_date_created( $date, $subscription ) {
|
|
if ( is_a( $subscription, 'WC_Subscription' ) && 12346 === $subscription->get_id() && 1 === $subscription->get_customer_id() ) {
|
|
return gmdate( 'Y-m-d H:i:s' );
|
|
}
|
|
|
|
return $date;
|
|
}
|
|
|
|
/**
|
|
* Allow early renewals for previewing emails.
|
|
*
|
|
* @param bool $can_renew_early Whether the subscription can be renewed early.
|
|
* @param WC_Subscription $subscription The subscription.
|
|
* @param int $user_id The user ID.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function allow_early_renewals_during_preview( $can_renew_early, $subscription, $user_id ) {
|
|
if ( 1 === $user_id ) {
|
|
return true;
|
|
}
|
|
|
|
return $can_renew_early;
|
|
}
|
|
|
|
/**
|
|
* Adds custom placeholders for subscription emails.
|
|
*
|
|
* @param WC_Email $email The email object.
|
|
*/
|
|
private function add_placeholders( $email ) {
|
|
if ( ! isset( $email->placeholders ) ) {
|
|
return;
|
|
}
|
|
|
|
$placeholders = [];
|
|
|
|
switch ( $this->email_type ) {
|
|
case 'WCS_Email_Customer_Notification_Subscription_Expiration':
|
|
case 'WCS_Email_Customer_Notification_Manual_Trial_Expiration':
|
|
case 'WCS_Email_Customer_Notification_Auto_Trial_Expiration':
|
|
case 'WCS_Email_Customer_Notification_Manual_Renewal':
|
|
case 'WCS_Email_Customer_Notification_Auto_Renewal':
|
|
// Pull the real values from the email object (Order or Subscription) if available.
|
|
if ( is_a( $email->object, 'WC_Subscription' ) ) {
|
|
$time_until_renewal = $email->get_time_until_date( $email->object, 'next_payment' );
|
|
$customer_first_name = $email->object->get_billing_first_name();
|
|
} else {
|
|
$time_until_renewal = human_time_diff( time(), time() + WEEK_IN_SECONDS );
|
|
$customer_first_name = 'John';
|
|
}
|
|
|
|
$placeholders['{time_until_renewal}'] = $time_until_renewal;
|
|
$placeholders['{customers_first_name}'] = $customer_first_name;
|
|
break;
|
|
case 'WCS_Email_Customer_Payment_Retry':
|
|
case 'WCS_Email_Payment_Retry':
|
|
$retry_time = is_a( $email->retry, 'WCS_Retry' )
|
|
? $email->retry->get_time()
|
|
: time() + ( 12 * HOUR_IN_SECONDS );
|
|
|
|
$placeholders['{retry_time}'] = wcs_get_human_time_diff( $retry_time );
|
|
break;
|
|
}
|
|
|
|
// Merge placeholders without overriding existing ones, and only adding those in the email.
|
|
$email->placeholders = wp_parse_args(
|
|
$placeholders,
|
|
$email->placeholders
|
|
);
|
|
}
|
|
}
|
|
|