LLMS_Notification_Controller_Upcoming_Payment_Reminder
Notification Controller: Upcoming Payment Reminder
Source Source
File: includes/notifications/controllers/class.llms.notification.controller.upcoming.payment.reminder.php
class LLMS_Notification_Controller_Upcoming_Payment_Reminder extends LLMS_Abstract_Notification_Controller { /** * Trigger Identifier * * @var string */ public $id = 'upcoming_payment_reminder'; /** * Action hooks used to trigger sending of the notification * * @var array */ protected $action_hooks = array( 'llms_send_upcoming_payment_reminder_notification', ); /** * Determines if test notifications can be sent * * @var bool */ protected $testable = array( 'basic' => false, 'email' => true, ); /** * Number of accepted arguments passed to the callback function * * @var integer */ protected $action_accepted_args = 2; /** * Add an action to trigger the notification to send * * @since 5.2.0 * * @return void */ protected function add_actions() { parent::add_actions(); // Add actions to recurring payment scheduling/unscheduling. add_action( 'llms_charge_recurring_payment_scheduled', array( $this, 'schedule_upcoming_payment_reminders' ), 10, 2 ); add_action( 'llms_charge_recurring_payment_unscheduled', array( $this, 'unschedule_upcoming_payment_reminders' ) ); } /** * Callback function called when the upcoming payment reminder notification is fired * * @since 5.2.0 * * @param int $order_id WP Post ID of the order. * @param string $type The notification type identifier. * @return boolean */ public function action_callback( $order_id = null, $type = null ) { // Make sure order_id and type have been provided. if ( ! $order_id || ! $type ) { return false; } // These checks are basically the same we do in LLMS_Controller_Orders::recurring_charge(). // Recurring payments disabled as a site feature when in staging mode. if ( ! LLMS_Site::get_feature( 'recurring_payments' ) ) { return false; } $order = llms_get_post( $order_id ); // Make sure the order still exists. if ( ! $order || ! is_a( $order, 'LLMS_Order' ) ) { return false; } $user_id = $order->get( 'user_id' ); // Check the user still exists. if ( ! get_user_by( 'id', $user_id ) ) { return false; } // Ensure Gateway is still available and supports recurring payments. $gateway = $order->get_gateway(); if ( is_wp_error( $gateway ) || ! $gateway->supports( 'recurring_payments' ) ) { return false; } $this->user_id = $user_id; $this->post_id = $order->get( 'id' ); $this->send( false, array( $type ) ); return true; } /** * Takes a subscriber type (student, author, etc) and retrieves a User ID. * * @since 5.2.0 * * @param string $subscriber Subscriber type string. * @return int|false */ protected function get_subscriber( $subscriber ) { switch ( $subscriber ) { case 'author': $order = llms_get_post( $this->post_id ); if ( ! is_a( $order, 'LLMS_Order' ) ) { return false; } $product = $order->get_product(); if ( is_a( $product, 'WP_Post' ) ) { return false; } $uid = $product->get( 'author' ); break; case 'student': $uid = $this->user_id; break; default: $uid = false; } return $uid; } /** * Get the translatable title for the notification * * Used on settings screens. * * @since 5.2.0 * * @return string */ public function get_title() { return __( 'Upcoming Payment Reminder', 'lifterlms' ); } /** * Setup the subscriber options for the notification * * @since 5.2.0 * * @param string $type The notification type identifier. * @return array */ protected function set_subscriber_options( $type ) { $options = array(); switch ( $type ) { case 'basic': $options[] = $this->get_subscriber_option_array( 'student', 'yes' ); break; case 'email': $options[] = $this->get_subscriber_option_array( 'author', 'no' ); $options[] = $this->get_subscriber_option_array( 'student', 'yes' ); $options[] = $this->get_subscriber_option_array( 'custom', 'no' ); break; } return $options; } /** * Cancels scheduled upcoming payment reminder notifications * * Does nothing if no payments are scheduled. * * @since 5.2.0 * * @param LLMS_Order $order Instance of the LLMS_Order which we'll schedule the payment reminder for. * @return void */ public function unschedule_upcoming_payment_reminders( $order ) { $types = array_keys( $this->get_supported_types() ); foreach ( $types as $type ) { $this->unschedule_upcoming_payment_reminder( $order, $type ); } } /** * Cancels a scheduled upcoming payment reminder notification type * * Does nothing if no payments are scheduled. * * @since 5.2.0 * * @param LLMS_Order $order Instance of the LLMS_Order which we'll schedule the payment reminder for. * @param string $type The notification type identifier. * @return void */ public function unschedule_upcoming_payment_reminder( $order, $type ) { $action_args = $this->get_recurring_payment_reminder_action_args( $order, $type ); if ( as_next_scheduled_action( 'llms_send_upcoming_payment_reminder_notification', $action_args ) ) { as_unschedule_action( 'llms_send_upcoming_payment_reminder_notification', $action_args ); } } /** * Schedule upcoming payment reminder notification * * @since 5.2.0 * * @param LLMS_Order $order Instance of the LLMS_Order which we'll schedule the payment reminder for. * @param int $payment_date Optional. The upcoming payment due date in Unix time format and UTC. Default is 0. * When not provided it'll be calculated from the order. * @return array */ public function schedule_upcoming_payment_reminders( $order, $payment_date = 0 ) { $types = array_keys( $this->get_supported_types() ); $return = array(); foreach ( $types as $type ) { $return[ $type ] = $this->schedule_upcoming_payment_reminder( $order, $type, $payment_date ); } return $return; } /** * Schedule upcoming payment reminder notification * * @since 5.2.0 * * @param LLMS_Order $order Instance of the LLMS_Order which we'll schedule the payment reminder for. * @param string $type The notification type identifier. * @param int $payment_date Optional. The upcoming payment due date in Unix time format and UTC. Default is 0. * When not provided it'll be calculated from the order. * @return WP_Error|int WP_Error either if there's no reminder date or if it's passed. Otherwise returns the return value of `as_schedule_single_action`: the action's ID. */ public function schedule_upcoming_payment_reminder( $order, $type, $payment_date = 0 ) { $action_args = $this->get_recurring_payment_reminder_action_args( $order, $type ); // Unschedule upcoming payment reminder (does nothing if no action scheduled). $this->unschedule_upcoming_payment_reminder( $order, $type ); // Convert our reminder date to Unix Time and UTC before passing to the scheduler. $reminder_date = $this->get_upcoming_payment_reminder_date( $order, $type, $payment_date ); // If no reminder date. if ( is_wp_error( $reminder_date ) ) { return $reminder_date; } // Or reminder date set in the past. if ( $reminder_date < llms_current_time( 'U', true ) ) { return new WP_Error( 'upcoming-payment-reminder-passed', __( 'Upcoming payment reminder passed', 'lifterlms' ) ); } // Schedule upcoming payment reminder. return as_schedule_single_action( $reminder_date, 'llms_send_upcoming_payment_reminder_notification', $action_args ); } /** * Retrieve the date to remind user before actual payment * * @since 5.2.0 * * @param LLMS_Order $order Instance of the LLMS_Order which we'll schedule the payment reminder for. * @param string $type The notification type identifier. * @param integer $payment_date Optional. The upcoming payment due date in Unix time format and UTC. Default is 0. * When not provided it'll be calculated from the order. * @return WP_Error|integer Returns a WP_Error if there's no payment scheduled, otherwise the reminder date in Unix format and UTC. */ private function get_upcoming_payment_reminder_date( $order, $type, $payment_date = 0 ) { $next_payment_date = $payment_date ? $payment_date : $order->get_recurring_payment_due_date_for_scheduler(); if ( is_wp_error( $next_payment_date ) ) { return $next_payment_date; } /** * Filters the number of days before the upcoming payment due date when to notify the customer * * The dynamic portion of this filter, `$this->id`, refers to the notification trigger identifier. * * @since 5.2.0 * * @param integer $days The number of days before the upcoming payment due date when to notify the customer. * @param LLMS_Order $order Order object. * @param string $type The notification type identifier. */ $days = apply_filters( "llms_notification_{$this->id}_reminder_days", $this->get_reminder_days( $type ), $order, $type ); // Sanitize: makes sure it's always a negative number. $days = -1 * max( 1, absint( $days ) ); /** * Filters the next upcoming payment reminder date * * The dynamic portion of this filter, `$this->id`, refers to the notification trigger identifier. * * @since 5.2.0 * * @param integer $upcoming_payment_reminder_time Unix timestamp for the next payment due date. * @param LLMS_Order $order Order object. * @param string $type The notification type identifier. */ $upcoming_payment_reminder_time = apply_filters( "llms_notification_{$this->id}_reminder_date", strtotime( "{$days} day", $next_payment_date ), $order, $type ); return $upcoming_payment_reminder_time; } /** * Retrieve arguments passed to order-related events processed by the action scheduler * * @since 5.2.0 * * @param LLMS_Order $order Instance of the LLMS_Order which we'll schedule the payment reminder for. */ private function get_recurring_payment_reminder_action_args( $order, $type ) { return array( 'order_id' => $order->get( 'id' ), 'type' => $type, ); } /** * Set array of additional options to be added to the notification view in the admin panel * * @since 5.2.0 * * @param string $type Type of the notification. * @return array */ protected function set_additional_options( $type ) { return array( array( 'id' => $this->get_option_name( $type . '_reminder_days' ), 'title' => __( 'Reminder days', 'lifterlms' ), 'desc' => '<br>' . __( 'The number of days before the upcoming payment due date when to notify the customer.', 'lifterlms' ), 'type' => 'number', 'value' => $this->get_reminder_days( $type ), 'custom_attributes' => array( 'min' => 1, ), ), ); } /** * Get an array of LifterLMS Admin Page settings to send test notifications * * Retrieves 25 recurring orders with an existing next payment date. * * @since 5.2.0 * * @param string $type Notification type [basic|email]. * @return array */ public function get_test_settings( $type ) { $query = new WP_Query( array( 'post_type' => 'llms_order', 'posts_per_page' => 25, 'post_status' => array( 'llms-active', 'llms-failed', 'llms-on-hold', 'llms-pending', 'llms-pending-cancel' ), 'meta_query' => array( 'relation' => 'and', array( 'key' => '_llms_order_type', 'value' => 'recurring', 'compare' => '=', ), array( 'key' => '_llms_date_next_payment', 'compare' => 'EXISTS', ), ), 'no_found_rows' => true, 'order_by' => 'ID', ) ); $options = array( '' => '', ); foreach ( $query->posts as $post ) { $order = llms_get_post( $post ); $student = llms_get_student( $order->get( 'user_id' ) ); if ( $order && $student ) { $options[ $order->get( 'id' ) ] = esc_attr( sprintf( // Translators: %1$d = The Order ID; %2$s The customer's full name; %3$s The product title. __( 'Order #%1$d from %2$s for "%3$s"', 'lifterlms' ), $order->get( 'id' ), $student->get_name(), $order->get( 'product_title' ) ) ); } } return array( array( 'class' => 'llms-select2', 'custom_attributes' => array( 'data-allow-clear' => true, 'data-placeholder' => __( 'Select a recurring order', 'lifterlms' ), ), 'default' => '', 'id' => 'order_id', 'desc' => '<br/>' . __( 'Send yourself a test notification using information from the selected recurring order.', 'lifterlms' ), 'options' => $options, 'title' => __( 'Send a Test', 'lifterlms' ), 'type' => 'select', ), ); } /** * Send a test notification to the currently logged in users * * @since 5.2.0 * * @param string $type Notification type [basic|email]. * @param array $data Array of test notification data as specified by $this->get_test_data(). * * @return int|false */ public function send_test( $type, $data = array() ) { if ( empty( $data['order_id'] ) ) { return; } $order = llms_get_post( $data['order_id'] ); $this->user_id = $order->get( 'user_id' ); $this->post_id = $order->get( 'id' ); return parent::send_test( $type ); } /** * Undocumented function * * @since 5.2.0 * * @param string $type The notification type identifier. * @param int $default Opional. The default value. Default is `1`. * @return int */ private function get_reminder_days( $type, $default = 1 ) { return $this->get_option( $type . '_reminder_days', $default ); } }
Expand full source code Collapse full source code View on GitHub
Methods Methods
- action_callback — Callback function called when the upcoming payment reminder notification is fired
- add_actions — Add an action to trigger the notification to send
- get_recurring_payment_reminder_action_args — Retrieve arguments passed to order-related events processed by the action scheduler
- get_reminder_days — Undocumented function
- get_subscriber — Takes a subscriber type (student, author, etc) and retrieves a User ID.
- get_test_settings — Get an array of LifterLMS Admin Page settings to send test notifications
- get_title — Get the translatable title for the notification
- get_upcoming_payment_reminder_date — Retrieve the date to remind user before actual payment
- schedule_upcoming_payment_reminder — Schedule upcoming payment reminder notification
- schedule_upcoming_payment_reminders — Schedule upcoming payment reminder notification
- send_test — Send a test notification to the currently logged in users
- set_additional_options — Set array of additional options to be added to the notification view in the admin panel
- set_subscriber_options — Setup the subscriber options for the notification
- unschedule_upcoming_payment_reminder — Cancels a scheduled upcoming payment reminder notification type
- unschedule_upcoming_payment_reminders — Cancels scheduled upcoming payment reminder notifications
Changelog Changelog
Version | Description |
---|---|
5.2.0 | Introduced. |