/** * Display credit card list on My Account page * * @access public * @return void */ public function display_card_list() { if (!is_user_logged_in()) { return; } $user_id = get_current_user_id(); // Get customer's cards $cards = get_user_meta($user_id, '_subscriptio_stripe_customer_cards', true); if (!empty($cards)) { $cards = maybe_unserialize($cards); // Get customer's default card $default_card = get_user_meta($user_id, '_subscriptio_stripe_customer_default_card', true); $default_card = !empty($default_card) ? $default_card : 'none'; Subscriptio::include_template('gateways/stripe/credit-card-list', array( 'cards' => $cards, 'default' => $default_card, )); } }
/** * Trigger a notification * * @access public * @param object $subscription * @param array $args * @param bool $send_to_admin * @return void */ public function trigger($subscription, $args = array(), $send_to_admin = false) { if (!$subscription || !isset($subscription->last_order_id)) { return; } $order = new WC_Order($subscription->last_order_id); if (!$order) { return; } $this->object = $order; if ($send_to_admin) { $this->recipient = get_option('admin_email'); } else { $this->recipient = $this->object->billing_email; } // Replace macros $this->find[] = '{order_number}'; $this->replace[] = $this->object->get_order_number(); // Check if this email type is enabled, recipient is set and we are not on a development website if (!$this->is_enabled() || !$this->get_recipient() || !Subscriptio::is_main_site()) { return; } // Get next action and next action date $next_action_datetime = Subscriptio_Scheduler::get_scheduled_event_datetime('subscriptio_scheduled_payment', $subscription->id); $next_action_is_overdue = false; if ($subscription->calculate_overdue_time()) { $next_action = __('marked overdue', 'subscriptio'); $next_action_is_overdue = true; $subsequent_action = $subscription->calculate_suspension_time() > 0 ? __('suspension', 'subscriptio') : __('cancellation', 'subscriptio'); } else if ($subscription->calculate_suspension_time() > 0) { $next_action = __('suspended', 'subscriptio'); } else { $next_action = __('cancelled', 'subscriptio'); } $this->template_variables = array( 'subscription' => $subscription, 'order' => $this->object, 'email_heading' => $this->get_heading(), 'sent_to_admin' => false, 'next_action' => $next_action, 'next_action_datetime' => $next_action_datetime, 'next_action_is_overdue' => $next_action_is_overdue, 'subsequent_action' => isset($subsequent_action) ? $subsequent_action : '', ); $this->send($this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments()); }
/** * Trigger a notification * * @access public * @param object $order * @param array $args * @param bool $send_to_admin * @return void */ public function trigger($order, $args = array(), $send_to_admin = false) { if (!$order) { return; } $this->object = $order; if ($send_to_admin) { $this->recipient = get_option('admin_email'); } else { $this->recipient = $this->object->billing_email; } // Replace macros $this->find[] = '{order_date}'; $this->replace[] = date_i18n(wc_date_format(), strtotime($this->object->order_date)); // Check if this email type is enabled, recipient is set and we are not on a development website if (!$this->is_enabled() || !$this->get_recipient() || !Subscriptio::is_main_site()) { return; } // Get subscription $subscription = Subscriptio_Order_Handler::get_subscriptions_from_order_id($order->id); $subscription = reset($subscription); if (!$subscription) { return; } $this->template_variables = array( 'subscription' => $subscription, 'order' => $this->object, 'email_heading' => $this->get_heading(), 'sent_to_admin' => false, ); $this->send($this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments()); }
/** * Trigger a notification * * @access public * @param object $subscription * @param array $args * @param bool $send_to_admin * @return void */ public function trigger($subscription, $args = array(), $send_to_admin = false) { if (!$subscription || !isset($subscription->last_order_id)) { return; } $order = new WC_Order($subscription->last_order_id); if (!$order) { return; } $this->object = $subscription; if ($send_to_admin) { $this->recipient = get_option('admin_email'); } else { $this->recipient = get_user_meta($subscription->user_id, 'billing_email', true); } // Check if this email type is enabled, recipient is set and we are not on a development website if (!$this->is_enabled() || !$this->get_recipient() || !Subscriptio::is_main_site()) { return; } // Get next action date and time $next_action_datetime = Subscriptio_Scheduler::get_scheduled_event_datetime('subscriptio_scheduled_cancellation', $subscription->id); $this->template_variables = array( 'subscription' => $this->object, 'order' => $order, 'email_heading' => $this->get_heading(), 'sent_to_admin' => false, 'next_action_datetime' => $next_action_datetime, ); $this->send($this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments()); }
// Exit if accessed directly if (!defined('ABSPATH')) { exit; } echo $email_heading . "\n\n"; echo sprintf(__('A new subscription renewal order has been generated and is pending payment. To pay for this order please use the following link: %s', 'subscriptio'), esc_url($order->get_checkout_payment_url())) . "\n\n"; echo "****************************************************\n\n"; do_action('woocommerce_email_before_order_table', $order, $sent_to_admin, $plain_text); echo sprintf(__('Order ID: %s', 'subscriptio'), $order->get_order_number()) . "\n"; echo sprintf(__('Subscription ID: %s', 'subscriptio'), $subscription->get_subscription_number()) . "\n"; do_action('woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text); Subscriptio::include_template('emails/plain/email-order-items', array('order' => $order, 'plain_text' => true)); echo "\n****************************************************\n\n"; do_action('woocommerce_email_after_order_table', $order, $sent_to_admin, $plain_text); echo __('Customer details', 'subscriptio') . "\n"; Subscriptio::include_template('emails/plain/email-customer-details', array('order' => $order, 'plain_text' => true)); echo "\n****************************************************\n\n"; echo apply_filters('woocommerce_email_footer_text', get_option('woocommerce_email_footer_text'));
/** * Cancel subscription * * @access public * @param int $subscription_id * @return void */ public static function cancel_subscription($subscription_id) { if ($subscription = self::get_subscription($subscription_id)) { // Check if subscription can be cancelled if (!$subscription->can_be_cancelled() || !$subscription->allow_customer_subscription_cancelling()) { self::redirect_to_subscription($subscription); return; } // Cancel and check if cancelled successfully if ($subscription->cancel_by_customer()) { wc_add_notice(__('Subscription has been cancelled.', 'subscriptio')); } else { wc_add_notice(__('Something went wrong...', 'subscriptio'), 'error'); } Subscriptio::include_template('myaccount/view-subscription', array('subscription' => $subscription)); } }
/** * Scheduled next payment event handler * * @access public * @param int $subscription_id * @return void */ public static function scheduled_payment($subscription_id) { // Start transaction $transaction = new Subscriptio_Transaction(null, 'payment_due'); // Load subscription if it's still valid $subscription = Subscriptio_Subscription::get_valid_subscription($subscription_id, $transaction); // Got a valid subscription object? if (!isset($subscription->status)) { return; } // Load related order $order = new WC_Order($subscription->last_order_id); if (!$order) { $transaction->update_result('error'); $transaction->update_note(__('Renewal order not found.', 'subscriptio'), true); return; } // Check if payment has been received manually - last order must be marked as processing or completed and payment_due date must be in the future if (time() <= $subscription->payment_due || in_array($order->status, array('processing', 'completed'))) { $transaction->update_result('error'); $transaction->update_note(__('Payment seems to be already received.', 'subscriptio'), true); return; } // Attempt to process automatic payment if this is main website if (apply_filters('subscriptio_process_automatic_payment', Subscriptio::is_main_site(), $order, $subscription)) { if (apply_filters('subscriptio_automatic_payment', false, $order, $subscription)) { return; } } // Now either set to overdue or suspend or cancel, depending on settings try { $overdue_end_time = $subscription->calculate_overdue_time(); $suspension_end_time = $subscription->calculate_suspension_time(); // This will be "fake" time for now in case $overdue_end_time is set // Overdue if ($overdue_end_time > 0) { // Set subscription to overdue $subscription->overdue(); // Update transaction $transaction->update_result('success'); $transaction->update_note(__('Payment not received. Subscription marked as overdue.', 'subscriptio'), true); // Schedule suspension and/or cancellation if ($suspension_end_time > 0) { self::schedule_suspension($subscription->id, $overdue_end_time); self::schedule_cancellation($subscription->id, $subscription->calculate_suspension_time($overdue_end_time)); $transaction->update_note(__('Suspension and cancellation scheduled.', 'subscriptio'), true); } else { self::schedule_cancellation($subscription->id, $overdue_end_time); $transaction->update_note(__('Cancellation scheduled.', 'subscriptio'), true); } } // Suspend else if ($suspension_end_time > 0) { // Not yet suspended? (can be suspended manually) if ($subscription->status != 'suspended') { // Suspend suscription $subscription->suspend(); // Update transaction $transaction->update_result('success'); $transaction->update_note(__('Payment not received. Subscription suspended.', 'subscriptio'), true); } else { $transaction->update_result('error'); $transaction->update_note(__('Payment not received but subscription is already suspended.', 'subscriptio'), true); } // Schedule cancellation self::schedule_cancellation($subscription->id, $suspension_end_time); $transaction->update_note(__('Cancellation scheduled.', 'subscriptio'), true); } // Cancel instantly (no overdue or suspension periods configured) else { // Cancel subscription $subscription->cancel(); // Update transaction $transaction->update_result('success'); $transaction->update_note(__('Payment not received. Subscription cancelled.', 'subscriptio'), true); } } catch (Exception $e) { $transaction->update_result('error'); $transaction->update_note($e->getMessage(), true); } }
<?php /** * Customer Subscription Completed Order email template */ // Exit if accessed directly if (!defined('ABSPATH')) { exit; } ?> <?php do_action('woocommerce_email_header', $email_heading); ?> <p><?php printf(__('Hi there. Your recent subscription renewal order on %s has been completed. Your order details are shown below for your reference:', 'subscriptio'), get_option('blogname')); ?></p> <?php do_action('woocommerce_email_before_order_table', $subscription, $sent_to_admin, $plain_text); ?> <h2><?php echo __('Order:', 'subscriptio') . ' ' . $order->get_order_number(); ?></h2> <?php Subscriptio::include_template('emails/email-order-items', array('order' => $order, 'plain_text' => false)); ?> <?php do_action('woocommerce_email_after_order_table', $order, $sent_to_admin, $plain_text); ?> <?php do_action('woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text); ?> <h2><?php _e('Customer details', 'subscriptio'); ?></h2> <?php Subscriptio::include_template('emails/email-order-items', array('order' => $order, 'plain_text' => false)); ?> <?php do_action('woocommerce_email_footer'); ?>
<?php /** * Customer Subscription Cancelled email template */ // Exit if accessed directly if (!defined('ABSPATH')) { exit; } echo $email_heading . "\n\n"; echo sprintf(__('Your subscription on %s has been suspended.', 'subscriptio'), get_option('blogname')) . "\n\n"; echo __('Details of the suspended subscription are shown below for your reference:', 'subscriptio') . "\n\n"; echo "****************************************************\n"; do_action('subscriptio_email_before_subscription_table', $subscription, $sent_to_admin, $plain_text); echo __('Subscription:', 'subscriptio') . ' ' . $subscription->get_subscription_number() . "\n"; Subscriptio::include_template('emails/plain/email-subscription-items', array('subscription' => $subscription, 'plain_text' => true)); echo "\n****************************************************\n\n"; do_action('subscriptio_email_after_subscription_table', $subscription, $sent_to_admin, $plain_text); echo apply_filters('woocommerce_email_footer_text', get_option('woocommerce_email_footer_text'));
/** * Get plain text email content * * @access public * @return string */ public function get_content_plain() { ob_start(); Subscriptio::include_template('emails/plain/' . $this->template, array_merge($this->template_variables, array('plain_text' => true))); return ob_get_clean(); }
/** * Hook filters/actions that need to be hooked later * * @access public * @return void */ public function on_init() { // Change cart item prices $cart_price_hook = Subscriptio::wc_version_gte('2.1') ? 'woocommerce_cart_item_price' : 'woocommerce_cart_item_price_html'; add_filter($cart_price_hook, array($this, 'change_cart_item_price_html'), 99, 3); }
<option value="<?php echo $unit_key; ?>" <?php echo $_subscriptio_price_time_unit == $unit_key ? 'selected="selected"' : ''; ?>><?php echo call_user_func($unit['translation_callback'], $unit_key, 2); ?></option> <?php endforeach; ?> </select> </p> <p class="form-field _subscriptio_free_trial_field"> <label for="_subscriptio_free_trial_time_value"><?php _e('Free trial', 'subscriptio'); ?></label> <input type="text" class="input-text subscriptio_product_page_half_width" id="_subscriptio_free_trial_time_value" name="_subscriptio_free_trial_time_value" placeholder="<?php _e('e.g. 3', 'subscriptio'); ?>" value="<?php echo $_subscriptio_free_trial_time_value; ?>"> <select id="_subscriptio_free_trial_time_unit" name="_subscriptio_free_trial_time_unit" class="select subscriptio_product_page_half_width" style="margin-left: 3px;"> <?php foreach (Subscriptio::get_time_units() as $unit_key => $unit): ?> <option value="<?php echo $unit_key; ?>" <?php echo $_subscriptio_free_trial_time_unit == $unit_key ? 'selected="selected"' : ''; ?>><?php echo call_user_func($unit['translation_callback'], $unit_key, 2); ?></option> <?php endforeach; ?> </select> </p> <p class="form-field _subscriptio_signup_fee_field"> <label for="_subscriptio_signup_fee"><?php _e('Sign-up fee', 'subscriptio'); ?> <?php echo (function_exists('get_woocommerce_currency_symbol') ? '(' . get_woocommerce_currency_symbol() . ')' : ''); ?></label> <input type="text" class="short" name="_subscriptio_signup_fee" id="_subscriptio_signup_fee" placeholder="<?php _e('e.g. 9.99', 'subscriptio'); ?>" value="<?php echo $_subscriptio_signup_fee; ?>"> </p> <p class="form-field _subscriptio_max_length_field"> <label for="_subscriptio_max_length_time_value"><?php _e('Max length', 'subscriptio'); ?></label> <input type="text" class="input-text subscriptio_product_page_half_width" id="_subscriptio_max_length_time_value" name="_subscriptio_max_length_time_value" placeholder="<?php _e('e.g. 90', 'subscriptio'); ?>" value="<?php echo $_subscriptio_max_length_time_value; ?>"> <select id="_subscriptio_max_length_time_unit" name="_subscriptio_max_length_time_unit" class="select subscriptio_product_page_half_width" style="margin-left: 3px;"> <?php foreach (Subscriptio::get_time_units() as $unit_key => $unit): ?> <option value="<?php echo $unit_key; ?>" <?php echo $_subscriptio_max_length_time_unit == $unit_key ? 'selected="selected"' : ''; ?>><?php echo call_user_func($unit['translation_callback'], $unit_key, 2); ?></option> <?php endforeach; ?> </select> </p> </div>
/** * Send selected email * * @access public * @param string $alias * @param object $object * @param array $args * @param array $customer_email * @return void */ public function send_email($alias, $object, $args = array(), $customer_email = false) { // Cancel sending emails if this is a duplicate website if (!apply_filters('subscriptio_send_email', Subscriptio::is_main_site(), $alias, $object, $args)) { return; } // Cancel sending email if we don't have such email if (!isset(self::$aliases[$alias])) { return; } global $woocommerce; $woocommerce_mailer = $woocommerce->mailer(); $emails = $woocommerce_mailer->get_emails(); $emails[self::$aliases[$alias]]->trigger($object, $args); // Check if we need to send a copy of customer email to admin if ($customer_email && $emails[self::$aliases[$alias]]->send_to_admin) { $emails[self::$aliases[$alias]]->trigger($object, $args, true); } }
/** * Check if customers are allowed to cancel subscriptions * * @access public * @return bool */ public function allow_customer_subscription_cancelling() { if (Subscriptio::option('customer_cancelling_allowed') && apply_filters('subscriptio_allow_subscription_cancelling', true)) { return true; } return false; }
/** * Credit card details form on Checkout * * @access public * @return void */ public function payment_fields() { // User logged in? if (is_user_logged_in()) { $user_id = get_current_user_id(); // Get customer's cards $cards = get_user_meta($user_id, '_subscriptio_stripe_customer_cards', true); if (!empty($cards)) { $cards = maybe_unserialize($cards); // Format card names foreach ($cards as $card_id => $card) { $brand = $card['brand'] != 'Unknown' ? $card['brand'] : __('Card', 'subscriptio-stripe'); $exp = Subscriptio_Stripe::format_expiration_date($card['exp_month'], $card['exp_year']); $cards[$card_id] = $brand . ' ' . __('ending with', 'subscriptio-stripe') . ' ' . $card['last4'] . ' (' . __('expires', 'subscriptio-stripe') . ' ' . $exp . ')'; } $cards['none'] = __('New Credit Card', 'subscriptio-stripe'); } else { $cards = array(); } // Get customer's default card $default_card = get_user_meta($user_id, '_subscriptio_stripe_customer_default_card', true); $default_card = !empty($default_card) ? $default_card : 'none'; } else { $cards = array(); $default_card = 'none'; } Subscriptio::include_template('gateways/stripe/credit-card-form', array( 'id' => $this->id, 'description' => $this->description, 'cards' => $cards, 'default_card' => $default_card, 'is_debug' => $this->debug == 'yes' ? true : false, 'is_inline' => $this->checkout_style == 'inline' ? true : false, )); }
<th class="subscriptio_list_recurring"><?php _e('Recurring', 'subscriptio'); ?></th> <th class="subscriptio_list_actions"> </th> </tr> </thead> <tbody> <?php foreach ($subscriptions as $subscription): ?> <tr class="subscriptio_subscription_list_subscription"> <td class="subscriptio_list_id"><?php echo '<a href="' . $subscription->get_frontend_link('view-subscription') . '">' . $subscription->get_subscription_number() . '</a>'; ?></td> <td class="subscriptio_list_status"><?php echo $subscription->get_formatted_status(true); ?></td> <td class="subscriptio_list_product"> <?php foreach (Subscriptio_Subscription::get_subscription_items($subscription->id) as $item): ?> <?php if (!$item['deleted']): ?> <?php Subscriptio::print_frontend_link_to_post($item['product_id'], $item['name'], '', ($item['quantity'] > 1 ? 'x ' . $item['quantity'] : '')); ?> <?php else: ?> <?php echo $item['name']; ?> <?php endif; ?> <?php endforeach; ?> </td> <td class="subscriptio_list_recurring"><?php echo $subscription->get_formatted_recurring_amount(); ?></td> <td class="subscriptio_list_actions"> <?php foreach ($subscription->get_frontend_actions() as $action_key => $action): ?> <a href="<?php echo $action['url']; ?>" class="button subscriptio_button_<?php echo sanitize_html_class($action_key); ?>"><?php echo $action['title']; ?></a> <?php endforeach; ?> </td> </tr> <?php endforeach; ?>
<a href="<?php echo $action['url']; ?>" id="subscriptio_button_<?php echo sanitize_html_class($action_key); ?>" class="button subscriptio_button subscriptio_button_<?php echo sanitize_html_class($action_key); ?>"><?php echo $action['title']; ?></a> <?php endforeach; ?> </dd> <?php endif; ?> </dl> </div> <?php if ($subscription->needs_shipping()): ?> <div class="subscriptio_frontend_details_shipping"> <h2><?php _e('Shipping Details', 'subscriptio'); ?></h2> <dl> <dt><?php _e('Shipping Method:', 'subscriptio'); ?></dt><dd><?php echo $subscription->shipping['name']; ?></dd> <dt><?php _e('Shipping Address:', 'subscriptio'); ?></dt><dd> <address><p> <?php echo wp_kses(Subscriptio::get_formatted_shipping_address($subscription->shipping_address), array('br' => array())); ?> </p></address> </dd> </dl> </div> <?php endif; ?> <div style="clear: both;"></div> </div> <h2><?php _e('Subscription Items', 'subscriptio'); ?></h2> <table class="shop_table subscriptio_frontend_items_list"> <thead> <tr> <th class="subscriptio_frontend_items_list_item"><?php _e('Item', 'subscriptio'); ?></th>
/** * Load existing subscription transaction * * @access public * @return void */ public function populate() { if (!$this->id) { return false; } // Get action $actions = self::get_actions(); $post_terms = wp_get_post_terms($this->id, 'sub_transaction_action'); $this->action = $post_terms[0]->slug; $this->action_title = $actions[$this->action]['title']; // Get status $results = self::get_results(); $post_terms = wp_get_post_terms($this->id, 'sub_transaction_result'); $this->result = $post_terms[0]->slug; $this->result_title = $results[$this->result]['title']; // Get other fields $post_meta = Subscriptio::unwrap_post_meta(get_post_meta($this->id)); // Load other properties from meta foreach (array('subscription_id', 'order_id', 'product_id', 'variation_id', 'time', 'iso_date', 'note') as $property) { $this->$property = isset($post_meta[$property]) ? maybe_unserialize($post_meta[$property]) : null; } }
/** * Return option * Warning: do not use in Subscriptio class constructor! * * @access public * @param string $key * @return string|bool */ public static function option($key) { $subscriptio = Subscriptio::get_instance(); return isset($subscriptio->opt['subscriptio_' . $key]) ? $subscriptio->opt['subscriptio_' . $key] : false; }
<?php echo Subscriptio::get_adjusted_datetime($scheduled_suspension); $scheduled_events = true; ?> </p> <?php endif; ?> <?php if ($scheduled_cancellation = Subscriptio_Scheduler::get_scheduled_event_timestamp('subscriptio_scheduled_cancellation', $subscription->id)): ?> <p> <strong><?php _e('Cancellation:', 'subscriptio'); ?></strong> <?php echo Subscriptio::get_adjusted_datetime($scheduled_cancellation); $scheduled_events = true; ?> </p> <?php endif; ?> <?php if ($scheduled_expiration = Subscriptio_Scheduler::get_scheduled_event_timestamp('subscriptio_scheduled_expiration', $subscription->id)): ?> <p> <strong><?php _e('Expiration:', 'subscriptio'); ?></strong> <?php echo Subscriptio::get_adjusted_datetime($scheduled_expiration); $scheduled_events = true; ?> </p> <?php endif; ?> <?php if (!$scheduled_events): ?> <p class="subscriptio_nothing_to_display"> <?php _e('No events scheduled.', 'subscriptio'); ?> </p> <?php endif; ?> </div> </div> </div>
/** * Create renewal order * Based on the WooCommerce procedure found in class-wc-checkout.php * * @access public * @param object $subscription * @return int */ public static function create_renewal_order($subscription) { // Get instance of main plugin class to access settings $subscriptio = Subscriptio::get_instance(); // Since WooCommerce 2.2 order statuses are stored as post statuses $post_status = Subscriptio::wc_version_gte('2.2') ? 'wc-pending' : 'publish'; // Prepare post properties $order_data = array( 'post_type' => 'shop_order', 'post_title' => sprintf(__('Order – %s', 'subscriptio'), strftime(_x('%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'subscriptio'))), 'post_status' => $post_status, 'ping_status' => 'closed', 'post_excerpt' => $subscription->renewal_customer_note, 'post_author' => 1, 'post_password' => uniqid('order_'), ); // Insert post into database $order_id = wp_insert_post($order_data, true); // Successfully inserted order post? if (is_wp_error($order_id)) { throw new Exception(__('Unable to create renewal order - failed inserting post.', 'subscriptio')); } // Load user meta $user_meta = Subscriptio::unwrap_post_meta(get_user_meta($subscription->user_id)); // Insert billing and shipping details $billing_shipping_fields = array( 'billing' => array( '_first_name', '_last_name', '_company', '_address_1', '_address_2', '_city', '_state', '_postcode', '_country', '_email', '_phone', ), ); // Check if subscription needs shipping if ($subscription->needs_shipping()) { $billing_shipping_fields['shipping'] = array( '_first_name', '_last_name', '_company', '_address_1', '_address_2', '_city', '_state', '_postcode', '_country', ); } // Iterate over billing/shipping fields and save them foreach ($billing_shipping_fields as $type => $fields) { foreach ($fields as $field) { // Billing fields if ($type == 'billing' && isset($user_meta[$type . $field])) { $field_value = $user_meta[$type . $field]; } // Shipping fields else if ($type == 'shipping' && isset($subscription->shipping_address['_' . $type . $field])) { $field_value = $subscription->shipping_address['_' . $type . $field]; } // In case some field does not exist else { $field_value = ''; } // Save field to post meta update_post_meta($order_id, '_' . $type . $field, $field_value); } } // Add other meta fields $other_meta_fields = array( '_order_shipping' => $subscription->renewal_order_shipping, '_order_shipping_tax' => $subscription->renewal_order_shipping_tax, '_cart_discount' => $subscription->renewal_cart_discount, '_order_discount' => $subscription->renewal_order_discount, '_order_tax' => $subscription->renewal_order_tax, '_order_total' => $subscription->renewal_order_total, '_customer_user' => $subscription->user_id, '_order_currency' => $subscription->renewal_order_currency, '_order_key' => 'wc_' . apply_filters('woocommerce_generate_order_key', uniqid('order_')), '_prices_include_tax' => $subscription->renewal_prices_include_tax, '_customer_ip_address' => $subscription->renewal_customer_ip_address, '_customer_user_agent' => $subscription->renewal_customer_user_agent, '_payment_method' => '', // Not yet paid '_payment_method_title' => '', // Not yet paid '_subscriptio_renewal' => 'yes', ); foreach ($other_meta_fields as $field_key => $field_value) { update_post_meta($order_id, $field_key, $field_value); } // Check if subscription product is variable $product_id_to_use = !empty($subscription->variation_id) ? $subscription->variation_id : $subscription->product_id; // Check if product still exists if (Subscriptio::product_is_active($product_id_to_use)) { // Load product object $product = new WC_Product($product_id_to_use); // Get product name $product_title = $product->get_title(); // Update product name on subscription if it was changed if ($product_title != $subscription->product_name) { $subscription->update_subscription_details(array( 'product_name' => $product_title, )); } } // If not - use saved product "snapshot" from previous order else { $product_title = $subscription->product_name; } // Add line item (product) to order $item_id = wc_add_order_item($order_id, array( 'order_item_name' => $product_title, 'order_item_type' => 'line_item', )); if (!$item_id) { throw new Exception(__('Unable to add product to renewal order.', 'subscriptio')); } // Add line item meta $item_meta = array( '_qty' => !empty($subscription->quantity) ? $subscription->quantity : 1, '_tax_class' => $subscription->renewal_tax_class, '_product_id' => $subscription->product_id, '_variation_id' => !empty($subscription->variation_id) ? $subscription->variation_id : '', '_line_subtotal' => wc_format_decimal($subscription->renewal_line_subtotal), '_line_subtotal_tax' => wc_format_decimal($subscription->renewal_line_subtotal_tax), '_line_total' => wc_format_decimal($subscription->renewal_line_total), '_line_tax' => wc_format_decimal($subscription->renewal_line_tax), ); foreach ($item_meta as $item_meta_key => $item_meta_value) { wc_add_order_item_meta($item_id, $item_meta_key, $item_meta_value); } // Save shipping info (if any) if (!empty($subscription->shipping)) { $shipping_item_id = wc_add_order_item($order_id, array( 'order_item_name' => $subscription->shipping['name'], 'order_item_type' => 'shipping', )); wc_add_order_item_meta($shipping_item_id, 'method_id', $subscription->shipping['method_id']); wc_add_order_item_meta($shipping_item_id, 'cost', wc_format_decimal($subscription->shipping['cost'])); } // Save taxes (if any) foreach ($subscription->taxes as $tax) { $tax_item_id = wc_add_order_item($order_id, array( 'order_item_name' => $tax['name'], 'order_item_type' => 'tax', )); wc_add_order_item_meta($tax_item_id, 'rate_id', $tax['rate_id']); wc_add_order_item_meta($tax_item_id, 'label', $tax['label']); wc_add_order_item_meta($tax_item_id, 'compound', $tax['compound']); wc_add_order_item_meta($tax_item_id, 'tax_amount', wc_format_decimal($tax['tax_amount'], 4)); wc_add_order_item_meta($tax_item_id, 'shipping_tax_amount', wc_format_decimal($tax['shipping_tax_amount'], 4)); } // Schedule payment due reminders if ($payment_due_timestamp = wp_next_scheduled('subscriptio_scheduled_payment', $subscription->id)) { foreach ($subscription->get_reminders('pre_payment_due', $payment_due_timestamp) as $timestamp) { Subscriptio_Scheduler::schedule_reminder($subscription->id, $timestamp); } } // Update appropriate subscription fields with new order id $subscription->update_subscription_details(array( 'last_order_id' => $order_id, 'all_order_ids' => $order_id, )); // Create a new order object $order = new WC_Order($order_id); // Set status to pending (pre- WooCommerce 2.2) if (!Subscriptio::wc_version_gte('2.2')) { $order->update_status('pending'); } // Send New Order email Subscriptio_Mailer::send('new_order', $order); return $order_id; }
<?php /** * Customer Subscription Paused email template */ // Exit if accessed directly if (!defined('ABSPATH')) { exit; } ?> <?php do_action('woocommerce_email_header', $email_heading); ?> <p><?php printf(__('Your subscription on %s has been paused.', 'subscriptio'), get_option('blogname')); ?></p> <p><?php _e('Details of the paused subscription are shown below for your reference:', 'subscriptio'); ?></p> <?php do_action('subscriptio_email_before_subscription_table', $subscription, $sent_to_admin, $plain_text); ?> <h2><?php echo __('Subscription:', 'subscriptio') . ' ' . $subscription->get_subscription_number(); ?></h2> <?php Subscriptio::include_template('emails/email-subscription-items', array('subscription' => $subscription, 'plain_text' => false)); ?> <?php do_action('subscriptio_email_after_subscription_table', $subscription, $sent_to_admin, $plain_text); ?> <?php do_action('woocommerce_email_footer'); ?>
/** * Return formatted subscription price to be displayed on product pages and cart * * @access public * @param int $id * @param bool $is_checkout * @param int $quantity * @param float $price_now * @param bool $is_variable * @param bool $variations_equal * @return string */ public static function get_formatted_subscription_price($id, $is_checkout = false, $quantity = 1, $price_now = null, $is_variable = false, $variations_equal = false) { $meta = Subscriptio::unwrap_post_meta(get_post_meta($id)); $recurring_price = Subscriptio_Subscription_Product::get_recurring_price($id); // Check if product is configured properly, if not - revert to standard price display if (!isset($meta['_subscriptio_price_time_unit']) || !isset($meta['_subscriptio_price_time_value'])) { return Subscriptio::get_formatted_price($recurring_price, get_woocommerce_currency()); } // Cart/checkout page? if ($is_checkout) { $recurring_price_html = self::format_recurring_amount(($recurring_price * $quantity), $meta['_subscriptio_price_time_unit'], $meta['_subscriptio_price_time_value']); // Payable now differs from recurring amount? if ($price_now != $recurring_price) { $html_now = Subscriptio::get_formatted_price(($price_now * $quantity), get_woocommerce_currency()); return sprintf(__('%1$s now then %2$s', 'subscriptio'), $html_now, $recurring_price_html); } else { return self::format_recurring_amount(($price_now * $quantity), $meta['_subscriptio_price_time_unit'], $meta['_subscriptio_price_time_value']); } } // Other pages else { $recurring_price_html = self::format_recurring_amount($recurring_price, $meta['_subscriptio_price_time_unit'], $meta['_subscriptio_price_time_value']); // Any signup fee? if (!empty($meta['_subscriptio_signup_fee'])) { $signup_fee = Subscriptio::get_formatted_price($meta['_subscriptio_signup_fee'], get_woocommerce_currency()); } // Any free trial? if (!empty($meta['_subscriptio_free_trial_time_value'])) { $time_units = Subscriptio::get_time_units(); if (isset($time_units[$meta['_subscriptio_free_trial_time_unit']]) && is_numeric($meta['_subscriptio_free_trial_time_value'])) { $free_trial = $meta['_subscriptio_free_trial_time_value'] . ' ' . call_user_func($time_units[$meta['_subscriptio_free_trial_time_unit']]['translation_callback'], $meta['_subscriptio_free_trial_time_unit'], $meta['_subscriptio_free_trial_time_value']); } else { $free_trial = ''; } } // Free trial & Signup fee if (!empty($meta['_subscriptio_signup_fee']) && !empty($meta['_subscriptio_free_trial_time_value'])) { if ($is_variable && !$variations_equal) { return sprintf(__('From %1$s', 'subscriptio'), $recurring_price_html); } else { return sprintf(__('%1$s with a free trial of %2$s and a sign-up fee of %3$s', 'subscriptio'), $recurring_price_html, $free_trial, $signup_fee); } } // Free trial else if (!empty($meta['_subscriptio_free_trial_time_value'])) { if ($is_variable && !$variations_equal) { return sprintf(__('From %1$s', 'subscriptio'), $recurring_price_html); } else { return sprintf(__('%1$s with a free trial of %2$s', 'subscriptio'), $recurring_price_html, $free_trial); } } // Signup fee else if (!empty($meta['_subscriptio_signup_fee'])) { if ($is_variable && !$variations_equal) { return sprintf(__('From %1$s', 'subscriptio'), $recurring_price_html); } else { return sprintf(__('%1$s with a sign-up fee of %2$s', 'subscriptio'), $recurring_price_html, $signup_fee); } } // Plain recurring price else { if ($is_variable && !$variations_equal) { return sprintf(__('From %s', 'subscriptio'), $recurring_price_html); } else { return $recurring_price_html; } } } }