From e71bc27c75dd651a698e97db1ae0f206f611b542 Mon Sep 17 00:00:00 2001 From: maximilianoRicoTabo Date: Sat, 7 Dec 2024 21:41:02 -0300 Subject: [PATCH] * Add Payment Email Classes --- classes/class.pmproemail.php | 155 +++-------- ...ro-email-template-payment-action-admin.php | 175 ++++++++++++ ...ss-pmpro-email-template-payment-action.php | 169 ++++++++++++ ...s-pmpro-email-template-payment-receipt.php | 254 ++++++++++++++++++ ...-pmpro-email-template-payment-reminder.php | 159 +++++++++++ includes/email-templates.php | 69 +---- includes/email.php | 8 + paid-memberships-pro.php | 4 + scheduled/crons.php | 5 + 9 files changed, 814 insertions(+), 184 deletions(-) create mode 100644 classes/email-templates/class-pmpro-email-template-payment-action-admin.php create mode 100644 classes/email-templates/class-pmpro-email-template-payment-action.php create mode 100644 classes/email-templates/class-pmpro-email-template-payment-receipt.php create mode 100644 classes/email-templates/class-pmpro-email-template-payment-reminder.php diff --git a/classes/class.pmproemail.php b/classes/class.pmproemail.php index 8816f189c..57442beb4 100644 --- a/classes/class.pmproemail.php +++ b/classes/class.pmproemail.php @@ -1134,8 +1134,7 @@ function sendCreditCardExpiringEmail($user = NULL, $order = NULL) { * @param object $user The WordPress user object. * @param MemberOrder $order The order object that is associated to the member. */ - function sendInvoiceEmail($user = NULL, $order = NULL) - { + function sendInvoiceEmail( $user = NULL, $order = NULL ) { global $wpdb, $current_user; if(!$user) $user = $current_user; @@ -1143,75 +1142,13 @@ function sendInvoiceEmail($user = NULL, $order = NULL) if(!$user || !$order) return false; + //Bail if no membership level in the order if ( empty( $order->membership_id ) ) { return false; } - $membership_level = pmpro_getSpecificMembershipLevelForUser($user->ID, $order->membership_id); - - $this->email = $user->user_email; - $this->subject = sprintf(__("Order for %s membership", "paid-memberships-pro"), get_option("blogname")); - - $this->data = array( - 'subject' => $this->subject, - 'header_name' => $user->display_name, - 'name' => $user->display_name, - 'user_login' => $user->user_login, - 'sitename' => get_option( 'blogname' ), - 'siteemail' => get_option( 'pmpro_from_email' ), - 'membership_id' => $membership_level->id, - 'membership_level_name' => $membership_level->name, - 'display_name' => $user->display_name, - 'user_email' => $user->user_email, - 'order_id' => $order->code, - 'order_total' => $order->get_formatted_total(), - 'order_date' => date_i18n( get_option( 'date_format' ), $order->getTimestamp() ), - 'billing_name' => $order->billing->name, - 'billing_street' => $order->billing->street, - 'billing_street2' => $order->billing->street2, - 'billing_city' => $order->billing->city, - 'billing_state' => $order->billing->state, - 'billing_zip' => $order->billing->zip, - 'billing_country' => $order->billing->country, - 'billing_phone' => $order->billing->phone, - 'cardtype' => $order->cardtype, - 'accountnumber' => hideCardNumber($order->accountnumber), - 'expirationmonth' => $order->expirationmonth, - 'expirationyear' => $order->expirationyear, - 'login_link' => pmpro_login_url(), - 'login_url' => pmpro_login_url(), - 'order_link' => pmpro_login_url( pmpro_url( 'invoice', '?invoice=' . $order->code ) ), - 'order_url' => pmpro_login_url( pmpro_url( 'invoice', '?invoice=' . $order->code ) ), - 'levels_url' => pmpro_url( 'levels' ) - ); - $this->data["billing_address"] = pmpro_formatAddress($order->billing->name, - $order->billing->street, - $order->billing->street2, - $order->billing->city, - $order->billing->state, - $order->billing->zip, - $order->billing->country, - $order->billing->phone); - - if($order->getDiscountCode()) { - if(!empty($order->discount_code->code)) - $this->data["discount_code"] = "

" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $order->discount_code->code . "

\n"; - else - $this->data["discount_code"] = "

" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $order->discount_code . "

\n"; - } else { - $this->data["discount_code"] = ""; - } - - $enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(CONVERT_TZ(enddate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1"); - if($enddate) - $this->data["membership_expiration"] = "

" . sprintf(__("This membership will expire on %s.", 'paid-memberships-pro' ), date_i18n(get_option('date_format'), $enddate)) . "

\n"; - else - $this->data["membership_expiration"] = ""; - - - $this->template = apply_filters("pmpro_email_template", "invoice", $this); - - return $this->sendEmail(); + $email = new PMPro_Email_Template_Payment_Receipt( $user, $order ); + $email->send(); } /** @@ -1440,44 +1377,25 @@ function sendBillableInvoiceEmail( $user = NULL, $order = NULL ) { * @param string $order_url The link to the order that is generated by Stripe. * @return void */ - function sendPaymentActionRequiredEmail($user = NULL, $order = NULL, $order_url = NULL) - { + function sendPaymentActionRequiredEmail( $user = NULL, $order = NULL, $order_url = NULL ) { global $current_user; if(!$user) $user = $current_user; - if(!$user || !$order) + if( !$user || !$order ) return false; // if an order URL wasn't passed in, grab it from the order - if(empty($order_url) && isset($order->order_url)) + if( empty( $order_url ) && isset( $order->order_url ) ) $order_url = $order->order_url; // still no order URL? bail - if(empty($order_url)) + if( empty( $order_url ) ) return false; - - $this->email = $user->user_email; - $this->subject = sprintf(__("Payment action required for your %s membership", 'paid-memberships-pro' ), get_option("blogname")); - - $this->template = "payment_action"; - $this->template = apply_filters("pmpro_email_template", $this->template, $this); + $email = new PMPro_Email_Template_Payment_Action( $user, $order_url ); + $email->send(); - $this->data = array( - 'subject' => $this->subject, - 'header_name' => $user->display_name, - 'name' => $user->display_name, - 'display_name' => $user->display_name, - 'user_login' => $user->user_login, - 'sitename' => get_option( 'blogname' ), - 'siteemail' => get_option( 'pmpro_from_email' ), - 'order_link' => $order_url, - 'order_url' => $order_url, - 'levels_url' => pmpro_url( 'levels' ) - ); - - return $this->sendEmail(); } /** @@ -1485,48 +1403,43 @@ function sendPaymentActionRequiredEmail($user = NULL, $order = NULL, $order_url * * @param object $user * @param MemberOrder $order - * @param string $invoice_url The link to the invoice that is generated by Stripe. + * @param string $order_url The url to the order that is generated by Stripe. * @return void */ - function sendPaymentActionRequiredAdminEmail($user = NULL, $order = NULL, $invoice_url = NULL) - { + function sendPaymentActionRequiredAdminEmail($user = NULL, $order = NULL, $order_url = NULL) { global $current_user; - if(!$user) + if( !$user ) $user = $current_user; - if(!$user || !$order) + if( !$user || !$order ) return false; // if an invoice URL wasn't passed in, grab it from the order - if(empty($invoice_url) && isset($order->invoice_url)) - $invoice_url = $order->invoice_url; + if( empty( $order_url ) && isset( $order->invoice_url ) ) + $order_url = $order->invoice_url; // still no invoice URL? bail - if(empty($invoice_url)) + if( empty( $order_url ) ) return false; - - $this->email = get_bloginfo("admin_email"); - $this->subject = sprintf(__("Payment action required: membership for %s at %s", 'paid-memberships-pro' ), $user->user_login, get_option("blogname")); - - $this->template = "payment_action_admin"; - $this->template = apply_filters("pmpro_email_template", $this->template, $this); + $email = new PMPro_Email_Template_Payment_Action_Admin( $user, $order_url ); + $email->send(); + } - $this->data = array( - 'subject' => $this->subject, - 'header_name' => $this->get_admin_name( $this->email ), - 'name' => $user->display_name, - 'display_name' => $user->display_name, - 'user_login' => $user->user_login, - 'sitename' => get_option('blogname'), - 'siteemail' => get_option('pmpro_from_email'), - 'user_email' => $user->user_email, - 'invoice_link' => $invoice_url, - 'invoice_url' => $invoice_url, - 'levels_url' => pmpro_url( 'levels' ) - ); - - return $this->sendEmail(); + /** + * Send the payment reminder email to a member. + * + * @param object $user The WordPress user object. + * @return void + * @since TBD + */ + function send_recurring_payment_reminder( $subscription_obj = NULL ) { + // Bail if we don't have a subscription object. + if ( ! $subscription_obj ) { + return false; + } + $email = new PMPro_Email_Template_Payment_Reminder( $subscription_obj ); + $email->send(); } /** diff --git a/classes/email-templates/class-pmpro-email-template-payment-action-admin.php b/classes/email-templates/class-pmpro-email-template-payment-action-admin.php new file mode 100644 index 000000000..540c1ec85 --- /dev/null +++ b/classes/email-templates/class-pmpro-email-template-payment-action-admin.php @@ -0,0 +1,175 @@ +user = $user; + $this->order_url = $order_url; + } + + /** + * Get the email template slug. + * + * @since TBD + * + * @return string The email template slug. + */ + public static function get_template_slug() { + return 'payment_action_admin'; + } + + /** + * Get the "nice name" of the email template. + * + * @since TBD + * + * @return string The "nice name" of the email template. + */ + public static function get_template_name() { + return __( 'Payment Action Required (admin)', 'paid-memberships-pro' ); + } + + /** + * Get "help text" to display to the admin when editing the email template. + * + * @since TBD + * + * @return string The "help text" to display to the admin when editing the email template. + */ + public static function get_template_description() { + return __( 'This email is sent to the site administrator when an attempted membership checkout requires additional customer authentication.', 'paid-memberships-pro' ); + } + + /** + * Get the default subject for the email. + * + * @since TBD + * + * @return string The default subject for the email. + */ + public static function get_default_subject() { + return __( "Payment action required: membership for !!user_login!! at !!sitename!!", 'paid-memberships-pro' ); + } + + /** + * Get the default body content for the email. + * + * @since TBD + * + * @return string The default body content for the email. + */ + public static function get_default_body() { + return __( '

A payment at !!sitename!! for !!user_login!! requires additional customer authentication to complete.

+

Below is a copy of the email we sent to !!user_email!! to notify them that they need to complete their payment:

+ +

Customer authentication is required to finish setting up your subscription at !!sitename!!.

+ +

Please complete the verification steps issued by your payment provider at the following link:

+

!!order_url!!

', 'paid-memberships-pro' ); + } + + /** + * Get the email address to send the email to. + * + * @since TBD + * + * @return string The email address to send the email to. + */ + public function get_recipient_email() { + return get_bloginfo( 'admin_email' ); + } + + /** + * Get the name of the email recipient. + * + * @since TBD + * + * @return string The name of the email recipient. + */ + public function get_recipient_name() { + //get user by email + $user = get_user_by( 'email', $this->get_recipient_email() ); + return $user->display_name; + } + + + /** + * Get the email template variables for the email paired with a description of the variable. + * + * @since TBD + * + * @return array The email template variables for the email (key => value pairs). + */ + public static function get_email_template_variables_with_description() { + return array( + '!!subject!!' => __( 'The default subject for the email. This will be removed in a future version.', 'paid-memberships-pro' ), + '!!header_name!!' => __( 'The name of the email recipient.', 'paid-memberships-pro' ), + '!!name!!' => __( 'The display name of the user.', 'paid-memberships-pro' ), + '!!user_login!!' => __( 'The username of the user.', 'paid-memberships-pro' ), + '!!display_name!!' => __( 'The display name of the user.', 'paid-memberships-pro' ), + '!!order_link!!' => __( 'The URL of the order.', 'paid-memberships-pro' ), + '!!order_url!!' => __( 'The URL of the order.', 'paid-memberships-pro' ), + '!!invoice_url!!' => __( 'The URL of the order. Legacy purpose', 'paid-memberships-pro' ), + '!!levels_url!!' => __( 'The URL of the membership levels page.', 'paid-memberships-pro' ), + ); + } + + /** + * Get the email template variables for the email. + * + * @since TBD + * + * @return array The email template variables for the email (key => value pairs). + */ + public function get_email_template_variables() { + $user = $this->user; + $order_url = $this->order_url; + return array( + "subject" => $this->subject, + "name" => $user->display_name, + "user_login" => $user->user_login, + "header_name" => $user->display_name, + "display_name" => $user->display_name, + "order_link" => $order_url, + "order_url" => $order_url, + "invoice_url" => $order_url, // Legacy purpose, remove in future version + "levels_url" => pmpro_url( 'levels' ) + ); + } +} + +/** + * Register the email template. + * + * @since TBD + * + * @param array $email_templates The email templates (template slug => email template class name) + * @return array The modified email templates array. + */ +function pmpro_email_templates_payment_action_admin( $email_templates ) { + $email_templates['payment_action_admin'] = 'PMPro_Email_Template_Payment_Action_Admin'; + return $email_templates; +} +add_filter( 'pmpro_email_templates', 'pmpro_email_templates_payment_action_admin' ); + diff --git a/classes/email-templates/class-pmpro-email-template-payment-action.php b/classes/email-templates/class-pmpro-email-template-payment-action.php new file mode 100644 index 000000000..4fccf1d24 --- /dev/null +++ b/classes/email-templates/class-pmpro-email-template-payment-action.php @@ -0,0 +1,169 @@ +user = $user; + $this->order_url = $order_url; + } + + /** + * Get the email template slug. + * + * @since TBD + * + * @return string The email template slug. + */ + public static function get_template_slug() { + return 'payment_action'; + } + + /** + * Get the "nice name" of the email template. + * + * @since TBD + * + * @return string The "nice name" of the email template. + */ + public static function get_template_name() { + return __( 'Payment Action Required', 'paid-memberships-pro' ); + } + + /** + * Get "help text" to display to the admin when editing the email template. + * + * @since TBD + * + * @return string The "help text" to display to the admin when editing the email template. + */ + public static function get_template_description() { + return __( 'This email is sent to the user when an attempted membership checkout requires additional customer authentication.', 'paid-memberships-pro' ); + } + + /** + * Get the default subject for the email. + * + * @since TBD + * + * @return string The default subject for the email. + */ + public static function get_default_subject() { + return __( "Payment action required for your !!sitename!! membership", 'paid-memberships-pro' ); + } + + /** + * Get the default body content for the email. + * + * @since TBD + * + * @return string The default body content for the email. + */ + public static function get_default_body() { + return __( '

Customer authentication is required to finish setting up your subscription at !!sitename!!.

+ +

Please complete the verification steps issued by your payment provider at the following link:

+

!!order_url!!

', 'paid-memberships-pro' ); + } + + /** + * Get the email address to send the email to. + * + * @since TBD + * + * @return string The email address to send the email to. + */ + public function get_recipient_email() { + return $this->user->user_email; + } + + /** + * Get the name of the email recipient. + * + * @since TBD + * + * @return string The name of the email recipient. + */ + public function get_recipient_name() { + return $this->user->display_name; + } + + + /** + * Get the email template variables for the email paired with a description of the variable. + * + * @since TBD + * + * @return array The email template variables for the email (key => value pairs). + */ + public static function get_email_template_variables_with_description() { + return array( + '!!subject!!' => __( 'The default subject for the email. This will be removed in a future version.', 'paid-memberships-pro' ), + '!!header_name!!' => __( 'The name of the email recipient.', 'paid-memberships-pro' ), + '!!name!!' => __( 'The display name of the user.', 'paid-memberships-pro' ), + '!!user_login!!' => __( 'The username of the user.', 'paid-memberships-pro' ), + '!!display_name!!' => __( 'The display name of the user.', 'paid-memberships-pro' ), + '!!order_link!!' => __( 'The URL of the order.', 'paid-memberships-pro' ), + '!!order_url!!' => __( 'The URL of the order.', 'paid-memberships-pro' ), + '!!invoice_url!!' => __( 'The URL of the order. Legacy purpose', 'paid-memberships-pro' ), + '!!levels_url!!' => __( 'The URL of the membership levels page.', 'paid-memberships-pro' ), + ); + } + + /** + * Get the email template variables for the email. + * + * @since TBD + * + * @return array The email template variables for the email (key => value pairs). + */ + public function get_email_template_variables() { + $user = $this->user; + $order_url = $this->order_url; + return array( + "subject" => $this->subject, + "name" => $user->display_name, + "user_login" => $user->user_login, + "header_name" => $user->display_name, + "display_name" => $user->display_name, + "order_link" => $order_url, + "order_url" => $order_url, + "invoice_url" => $order_url, // Legacy purpose, remove in future version + "levels_url" => pmpro_url( 'levels' ) + ); + } +} + +/** + * Register the email template. + * + * @since TBD + * + * @param array $email_templates The email templates (template slug => email template class name) + * @return array The modified email templates array. + */ +function pmpro_email_templates_payment_action( $email_templates ) { + $email_templates['payment_action'] = 'PMPro_Email_Template_Payment_Action'; + return $email_templates; +} +add_filter( 'pmpro_email_templates', 'pmpro_email_templates_payment_action' ); diff --git a/classes/email-templates/class-pmpro-email-template-payment-receipt.php b/classes/email-templates/class-pmpro-email-template-payment-receipt.php new file mode 100644 index 000000000..4350824d7 --- /dev/null +++ b/classes/email-templates/class-pmpro-email-template-payment-receipt.php @@ -0,0 +1,254 @@ + +user = $user; + $this->order = $order; + } + + /** + * Get the email template slug. + * + * @since TBD + * + * @return string The email template slug. + */ + public static function get_template_slug() { + return 'invoice'; + } + + /** + * Get the "nice name" of the email template. + * + * @since TBD + * + * @return string The "nice name" of the email template. + */ + public static function get_template_name() { + return __( 'Recurring Payment Receipt', 'paid-memberships-pro' ); + } + + /** + * Get "help text" to display to the admin when editing the email template. + * + * @since TBD + * + * @return string The "help text" to display to the admin when editing the email template. + */ + public static function get_template_description() { + return __( 'This email is sent to the member each time a new subscription payment is made.', 'paid-memberships-pro' ); + } + + /** + * Get the default subject for the email. + * + * @since TBD + * + * @return string The default subject for the email. + */ + public static function get_default_subject() { + return __( "Recurring payment receipt for !!sitename!! membership", 'paid-memberships-pro' ); + } + + /** + * Get the default body content for the email. + * + * @since TBD + * + * @return string The default body content for the email. + */ + public static function get_default_body() { + return __( '

Thank you for your membership to !!sitename!!. Below is a receipt for your most recent membership order.

+ +

Account: !!display_name!! (!!user_email!!)

+

+ Order #!!order_id!! on !!order_date!!
+ Total Billed: !!order_total!! +

+

+ Billing Information:
+ !!billing_address!! +

+ +

+ !!cardtype!!: !!accountnumber!!
+ Expires: !!expirationmonth!!/!!expirationyear!! +

+ +

Log in to your membership account here: !!login_url!!

+

To view an online version of this order, click here: !!order_url!!

', 'paid-memberships-pro' ); + } + + /** + * Get the email address to send the email to. + * + * @since TBD + * + * @return string The email address to send the email to. + */ + public function get_recipient_email() { + return $this->user->user_email; + } + + /** + * Get the name of the email recipient. + * + * @since TBD + * + * @return string The name of the email recipient. + */ + public function get_recipient_name() { + return $this->user->display_name; + } + + + /** + * Get the email template variables for the email paired with a description of the variable. + * + * @since TBD + * + * @return array The email template variables for the email (key => value pairs). + */ + public static function get_email_template_variables_with_description() { + return array( + '!!subject!!' => __( 'The default subject for the email. This will be removed in a future version.', 'paid-memberships-pro' ), + '!!header_name!!' => __( 'The name of the email recipient.', 'paid-memberships-pro' ), + '!!name!!' => __( 'The display name of the user.', 'paid-memberships-pro' ), + '!!membership_id!!' => __( 'The ID of the membership level.', 'paid-memberships-pro' ), + '!!membership_level_name!!' => __( 'The name of the membership level.', 'paid-memberships-pro' ), + '!!user_login!!' => __( 'The username of the user.', 'paid-memberships-pro' ), + '!!user_email!!' => __( 'The email address of the user.', 'paid-memberships-pro' ), + '!!display_name!!' => __( 'The display name of the user.', 'paid-memberships-pro' ), + '!!order_id!!' => __( 'The order ID.', 'paid-memberships-pro' ), + '!!order_total!!' => __( 'The total amount of the order.', 'paid-memberships-pro' ), + '!!order_date!!' => __( 'The date of the order.', 'paid-memberships-pro' ), + '!!order_link!!' => __( 'The URL of the order.', 'paid-memberships-pro' ), + '!!order_url!!' => __( 'The URL of the order.', 'paid-memberships-pro' ), + '!!billing_name!!' => __( 'The name of the billing contact.', 'paid-memberships-pro' ), + '!!billing_street!!' => __( 'The street address of the billing contact.', 'paid-memberships-pro' ), + '!!billing_street2!!' => __( 'The second line of the street address of the billing contact.', 'paid-memberships-pro' ), + '!!billing_city!!' => __( 'The city of the billing contact.', 'paid-memberships-pro' ), + '!!billing_state!!' => __( 'The state of the billing contact.', 'paid-memberships-pro' ), + '!!billing_zip!!' => __( 'The ZIP code of the billing contact.', 'paid-memberships-pro' ), + '!!billing_country!!' => __( 'The country of the billing contact.', 'paid-memberships-pro' ), + '!!billing_phone!!' => __( 'The phone number of the billing contact.', 'paid-memberships-pro' ), + '!!billing_address!!' => __( 'The formatted billing address.', 'paid-memberships-pro' ), + '!!cardtype!!' => __( 'The type of credit card used for the order.', 'paid-memberships-pro' ), + '!!accountnumber!!' => __( 'The last four digits of the credit card used for the order.', 'paid-memberships-pro' ), + '!!expirationmonth!!' => __( 'The expiration month of the credit card used for the order.', 'paid-memberships-pro' ), + '!!expirationyear!!' => __( 'The expiration year of the credit card used for the order.', 'paid-memberships-pro' ), + '!!discount_code!!' => __( 'The discount code used for the order.', 'paid-memberships-pro' ), + '!!membership_expiration!!' => __( 'The expiration date of the membership level.', 'paid-memberships-pro' ), + + + + ); + } + + /** + * Get the email template variables for the email. + * + * @since TBD + * + * @return array The email template variables for the email (key => value pairs). + */ + public function get_email_template_variables() { + global $wpdb; + $user = $this->user; + $order = $this->order; + $membership_level = pmpro_getLevel( $order->membership_id ); + + //Get discount code if it exists + $discount_code = ""; + if( $order->getDiscountCode() && !empty( $order->discount_code->code ) ) { + $discount_code = "

" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $order->discount_code->code . "

\n"; + } else { + $discount_code = "

" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $order->discount_code . "

\n"; + } + + //Get membership expiration date + $enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(CONVERT_TZ(enddate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1"); + if( $enddate ) { + $membership_expiration = "

" . sprintf(__("This membership will expire on %s.", 'paid-memberships-pro' ), date_i18n(get_option('date_format'), $enddate)) . "

\n"; + } else { + $membership_expiration = ""; + } + + $email_template_variables = array( + 'subject' => $this->get_default_subject(), + 'header_name' => $this->get_recipient_name(), + 'name' => $this->get_recipient_name(), + 'display_name' => $this->get_recipient_name(), + 'user_login' => $user->user_login, + 'membership_id' => $membership_level->id, + 'membership_level_name' => $membership_level->name, + 'user_email' => $user->user_email, + 'order_id' => $order->code, + 'order_total' => $order->get_formatted_total(), + 'order_date' => date_i18n( get_option( 'date_format' ), $order->getTimestamp() ), + 'order_link' => pmpro_login_url( pmpro_url( 'invoice', '?invoice=' . $order->code ) ), + 'order_url' => pmpro_login_url( pmpro_url( 'invoice', '?invoice=' . $order->code ) ), + 'billing_name' => $order->billing->name, + 'billing_street' => $order->billing->street, + 'billing_street2' => $order->billing->street2, + 'billing_city' => $order->billing->city, + 'billing_state' => $order->billing->state, + 'billing_zip' => $order->billing->zip, + 'billing_country' => $order->billing->country, + 'billing_phone' => $order->billing->phone, + 'billing_address'=> pmpro_formatAddress( $order->billing->name, + $order->billing->street, + $order->billing->street2, + $order->billing->city, + $order->billing->state, + $order->billing->zip, + $order->billing->country, + $order->billing->phone ), + 'cardtype' => $order->cardtype, + 'accountnumber' => hideCardNumber( $order->accountnumber ), + 'expirationmonth' => $order->expirationmonth, + 'expirationyear' => $order->expirationyear, + 'discount_code' => $discount_code, + 'membership_expiration' => $membership_expiration + ); + + return $email_template_variables; + } +} + +/** + * Register the email template. + * + * @since TBD + * + * @param array $email_templates The email templates (template slug => email template class name) + * @return array The modified email templates array. + */ +function pmpro_email_templates_payment_receipt( $email_templates ) { + $email_templates['invoice'] = 'PMPro_Email_Template_Payment_Receipt'; + return $email_templates; +} +add_filter( 'pmpro_email_templates', 'pmpro_email_templates_payment_receipt' ); \ No newline at end of file diff --git a/classes/email-templates/class-pmpro-email-template-payment-reminder.php b/classes/email-templates/class-pmpro-email-template-payment-reminder.php new file mode 100644 index 000000000..5b036c475 --- /dev/null +++ b/classes/email-templates/class-pmpro-email-template-payment-reminder.php @@ -0,0 +1,159 @@ +subscription_obj = $subscription_obj; + } + + /** + * Get the email template slug. + * + * @since TBD + * + * @return string The email template slug. + */ + public static function get_template_slug() { + return 'membership_recurring'; + } + + /** + * Get the "nice name" of the email template. + * + * @since TBD + * + * @return string The "nice name" of the email template. + */ + public static function get_template_name() { + return __( 'Membership Recurring', 'paid-memberships-pro' ); + } + + /** + * Get "help text" to display to the admin when editing the email template. + * + * @since TBD + * + * @return string The "help text" to display to the admin when editing the email template. + */ + public static function get_template_description() { + return __( 'This email is sent when a subscription is approaching its renewal date. The additional placeholders !!renewaldate!! and !!billing_amount!! can be used to print the date that the subscription will renew and the renewal price.', 'paid-memberships-pro' ); + } + + /** + * Get the default subject for the email. + * + * @since TBD + * + * @return string The default subject for the email. + */ + public static function get_default_subject() { + return __( "Your membership at !!sitename!! will end soon", 'paid-memberships-pro' ); + } + + /** + * Get the default body content for the email. + * + * @since TBD + * + * @return string The default body content for the email. + */ + public static function get_default_body() { + return __( '

Thank you for your membership to !!sitename!!.

+ +

This is just a reminder that your !!membership_level_name!! membership will automatically renew on !!renewaldate!!.

+ +

Account: !!display_name!! (!!user_email!!)

+ +

If for some reason you do not want to renew your membership you can cancel by clicking here: !!cancel_link!!

', 'paid-memberships-pro' ); + } + + /** + * Get the email address to send the email to. + * + * @since TBD + * + * @return string The email address to send the email to. + */ + public function get_recipient_email() { + return $this->user->user_email; + } + + /** + * Get the name of the email recipient. + * + * @since TBD + * + * @return string The name of the email recipient. + */ + public function get_recipient_name() { + return $this->user->display_name; + } + + + /** + * Get the email template variables for the email paired with a description of the variable. + * + * @since TBD + * + * @return array The email template variables for the email (key => value pairs). + */ + public static function get_email_template_variables_with_description() { + return array( + 'membership_level_name' => __( 'The name of the membership level.', 'paid-memberships-pro' ), + 'renewaldate' => __( 'The date of the next payment date.', 'paid-memberships-pro' ), + 'display_name' => __( 'The display name of the user.', 'paid-memberships-pro' ), + 'user_email' => __( 'The email address of the user.', 'paid-memberships-pro' ), + 'cancel_link' => __( 'The link to cancel the subscription.', 'paid-memberships-pro' ), + ); + } + + /** + * Get the email template variables for the email. + * + * @since TBD + * + * @return array The email template variables for the email (key => value pairs). + */ + public function get_email_template_variables() { + $subscription_obj = $this->subscription_obj; + $membership_id = $subscription_obj->get_membership_level_id(); + $membership_level = pmpro_getLevel( $membership_id ); + $user = get_userdata( $subscription_obj->get_user_id() ); + + return array( + 'membership_level_name' => $membership_level->name, + 'renewaldate' => date_i18n( get_option( 'date_format' ), $subscription_obj->get_next_payment_date() ), + 'display_name' => $user->display_name, + 'user_email' => $user->user_email, + 'cancel_link' => wp_login_url( pmpro_url( 'cancel' ) ), + ); + } +} + +/** + * Register the email template. + * + * @since TBD + * + * @param array $email_templates The email templates (template slug => email template class name) + * @return array The modified email templates array. + */ +function pmpro_email_templates_membership_recurring( $email_templates ) { + $email_templates['membership_recurring'] = 'PMPro_Email_Template_Payment_Reminder'; + return $email_templates; +} +add_filter( 'pmpro_email_templates', 'pmpro_email_templates_membership_recurring' ); \ No newline at end of file diff --git a/includes/email-templates.php b/includes/email-templates.php index e0d2734a2..1cd114918 100644 --- a/includes/email-templates.php +++ b/includes/email-templates.php @@ -250,30 +250,6 @@

', 'paid-memberships-pro' ), 'help_text' => __( 'This email is sent when a member\'s payment method will be expiring soon. This allows the member to update their payment method before a payment failure, which may result in lost access to member features.', 'paid-memberships-pro' ) ), - 'invoice' => array( - 'subject' => __( "Recurring payment receipt for !!sitename!! membership", 'paid-memberships-pro' ), - 'description' => __('Recurring Payment Receipt', 'paid-memberships-pro'), - 'body' => __( '

Thank you for your membership to !!sitename!!. Below is a receipt for your most recent membership order.

- -

Account: !!display_name!! (!!user_email!!)

-

- Order #!!order_id!! on !!order_date!!
- Total Billed: !!order_total!! -

-

- Billing Information:
- !!billing_address!! -

- -

- !!cardtype!!: !!accountnumber!!
- Expires: !!expirationmonth!!/!!expirationyear!! -

- -

Log in to your membership account here: !!login_url!!

-

To view an online version of this order, click here: !!order_url!!

', 'paid-memberships-pro' ), - 'help_text' => __( 'This email is sent to the member each time a new subscription payment is made.', 'paid-memberships-pro' ) - ), 'membership_expired' => array( 'subject' => __( "Your membership at !!sitename!! has ended", 'paid-memberships-pro' ), 'description' => __('Membership Expired', 'paid-memberships-pro'), @@ -328,49 +304,16 @@

Log in to your WordPress admin here: !!login_url!!

', 'paid-memberships-pro' ), 'help_text' => __( 'This email is sent to the admin as confirmation of a refunded payment. The email is sent after your membership site receives notification of a successful payment refund through your gateway.', 'paid-memberships-pro' ) ), - 'membership_recurring' => array( - 'subject' => __( "Your membership at !!sitename!! will renew soon", 'paid-memberships-pro' ), - 'description' => __('Recurring Payment Reminder', 'paid-memberships-pro'), - 'body' => __( '

Thank you for your membership to !!sitename!!.

- -

This is just a reminder that your !!membership_level_name!! membership will automatically renew on !!renewaldate!!.

- -

Account: !!display_name!! (!!user_email!!)

- -

If for some reason you do not want to renew your membership you can cancel by clicking here: !!cancel_link!!

', 'paid-memberships-pro' ), - 'help_text' => __( 'This email is sent when a subscription is approaching its renewal date. The additional placeholders !!renewaldate!! and !!billing_amount!! can be used to print the date that the subscription will renew and the renewal price.', 'paid-memberships-pro' ) - ), ); -//we can hide the payment action required emails if default gateway isn't Stripe. -$default_gateway = get_option( 'pmpro_gateway' ); -if( 'stripe' === $default_gateway ) { - $pmpro_email_templates_defaults = array_merge( $pmpro_email_templates_defaults, array( - 'payment_action' => array( - 'subject' => __( "Payment action required for your !!sitename!! membership", 'paid-memberships-pro' ), - 'description' => __('Payment Action Required', 'paid-memberships-pro' ), - 'body' => __( '

Customer authentication is required to finish setting up your subscription at !!sitename!!.

- -

Please complete the verification steps issued by your payment provider at the following link:

-

!!invoice_url!!

', 'paid-memberships-pro' ), - 'help_text' => __( 'This email is sent to the user when an attempted membership checkout requires additional customer authentication.', 'paid-memberships-pro' ) - ), - 'payment_action_admin' => array( - 'subject' => __( "Payment action required: membership for !!user_login!! at !!sitename!!", 'paid-memberships-pro' ), - 'description' => __('Payment Action Required (admin)', 'paid-memberships-pro'), - 'body' => __( '

A payment at !!sitename!! for !!user_login!! requires additional customer authentication to complete.

-

Below is a copy of the email we sent to !!user_email!! to notify them that they need to complete their payment:

- -

Customer authentication is required to finish setting up your subscription at !!sitename!!.

- -

Please complete the verification steps issued by your payment provider at the following link:

-

!!invoice_url!!

', 'paid-memberships-pro' ), - 'help_text' => __( 'This email is sent to the site administrator when an attempted membership checkout requires additional customer authentication.', 'paid-memberships-pro' ) - ) - ) ); -} // Add any templates registered via the PMPro_Email_Template class. $registered_templates = PMPro_Email_Template::get_all_email_templates(); +$default_gateway = get_option( 'pmpro_gateway' ); +// if gateway is not stripe, remove the payment action emails +if( 'stripe' !== $default_gateway ) { + unset( $registered_templates['payment_action'] ); + unset( $registered_templates['payment_action_admin'] ); +} foreach ( $registered_templates as $registered_template_slug => $registered_template_class ) { $pmpro_email_templates_defaults[ $registered_template_slug ] = array( 'subject' => $registered_template_class::get_default_subject(), diff --git a/includes/email.php b/includes/email.php index c716176a6..12054636d 100644 --- a/includes/email.php +++ b/includes/email.php @@ -296,6 +296,10 @@ function pmpro_email_templates_send_test() { $test_user = $current_user; + + //test subscription object + $test_subscription = new PMPro_Subscription( array( 'user_id' => $test_user->ID, 'membership_level_id' => $test_user->membership_level->id, 'next_payment_date' => date( 'Y-m-d', strtotime( '+1 month' ) ) ) ); + // Grab the first membership level defined as a "test level" to use $all_levels = pmpro_getAllLevels( true); $test_user->membership_level = array_pop( $all_levels ); @@ -379,6 +383,10 @@ function pmpro_email_templates_send_test() { $send_email = 'sendPaymentActionRequiredAdminEmail'; $params = array($test_user, $test_order, "http://www.example-notification-url.com/not-a-real-site"); break; + case 'membership_recurring': + $send_email = 'send_recurring_payment_reminder'; + $params = array( $test_subscription ); + break; default: $send_email = 'sendEmail'; $params = array(); diff --git a/paid-memberships-pro.php b/paid-memberships-pro.php index fc919808d..95f52852f 100644 --- a/paid-memberships-pro.php +++ b/paid-memberships-pro.php @@ -55,6 +55,10 @@ require_once( PMPRO_DIR . '/classes/email-templates/class-pmpro-email-template-cancel-admin.php' ); // cancel email template require_once( PMPRO_DIR . '/classes/email-templates/class-pmpro-email-template-admin-change.php' ); // change email template require_once( PMPRO_DIR . '/classes/email-templates/class-pmpro-email-template-admin-change-admin.php' ); // change email template +require_once( PMPRO_DIR . '/classes/email-templates/class-pmpro-email-template-payment-action.php' ); // expiration email template +require_once( PMPRO_DIR . '/classes/email-templates/class-pmpro-email-template-payment-action-admin.php' ); // expiration email template +require_once( PMPRO_DIR . '/classes/email-templates/class-pmpro-email-template-payment-receipt.php' ); // invoice email template +require_once( PMPRO_DIR . '/classes/email-templates/class-pmpro-email-template-payment-reminder.php' ); // recurring payment email reminder template require_once( PMPRO_DIR . '/includes/filters.php' ); // filters, hacks, etc, moved into the plugin require_once( PMPRO_DIR . '/includes/reports.php' ); // load reports for admin (reports may also include tracking code, etc) diff --git a/scheduled/crons.php b/scheduled/crons.php index ff3720787..739012614 100644 --- a/scheduled/crons.php +++ b/scheduled/crons.php @@ -330,6 +330,11 @@ function pmpro_cron_recurring_payment_reminders() { */ $send_email = apply_filters( 'pmpro_send_recurring_payment_reminder_email', true, $subscription_obj, $days ); + if ( $send_emails ) { + $pmproemail = new PMProEmail(); + $pmproemail->send_recurring_payment_reminder( $user, $subscription_obj->get_membership_level_id() ); + } + /** * @filter pmprorm_send_reminder_to_user *