/** * When a product is added to the cart, check if it is being added to switch a subscription and if so, * make sure it's valid (i.e. not the same subscription). * * @since 1.4 */ public static function validate_switch_request($is_valid, $product_id, $quantity, $variation_id = '') { global $woocommerce; if (!isset($_GET['switch-subscription'])) { return $is_valid; } $subscription = WC_Subscriptions_Manager::get_subscription($_GET['switch-subscription']); // Check if the chosen variation's attributes are different to the existing subscription's attributes (to support switching between a "catch all" variation) $original_order = new WC_Order($subscription['order_id']); $item = WC_Subscriptions_Order::get_item_by_product_id($original_order, $subscription['product_id']); $identical_attributes = true; foreach ($_POST as $key => $value) { if (false !== strpos($key, 'attribute_') && !empty($item[str_replace('attribute_', '', $key)]) && $item[str_replace('attribute_', '', $key)] != $value) { $identical_attributes = false; break; } } if ($product_id == $subscription['product_id'] && (empty($variation_id) || $variation_id == $subscription['variation_id'] && true == $identical_attributes)) { WC_Subscriptions::add_notice(__('You can not switch to the same subscription.', 'woocommerce-subscriptions'), 'error'); $is_valid = false; } return $is_valid; }
public function email_replacements($reps, $email_data, $email_order, $email_row) { global $wpdb, $woocommerce; $email_type = $email_row->email_type; $order_date = ''; $order_datetime = ''; $order_id = ''; if ($email_order->order_id) { $order = new WC_Order($email_order->order_id); $order_date = date(get_option('date_format'), strtotime($order->order_date)); $order_datetime = date(get_option('date_format') . ' ' . get_option('time_format'), strtotime($order->order_date)); $order_id = apply_filters('woocommerce_order_number', '#' . $email_order->order_id, $order); $item = WC_Subscriptions_Order::get_item_by_product_id($order); $item_id = WC_Subscriptions_Order::get_items_product_id($item); $renewal = WC_Subscriptions_Order::get_next_payment_timestamp($order, $item_id); $renew_date = date(get_option('date_format'), $renewal); // calc days to renew $now = current_time('timestamp'); $diff = $renewal - $now; $days_to_renew = 0; if ($diff > 0) { $days_to_renew = floor($diff / 86400); } $item_url = FUE::create_email_url($email_order->id, $email_row->id, $email_data['user_id'], $email_data['email_to'], get_permalink($item_id)); $categories = ''; if ($item_id) { $cats = get_the_terms($item_id, 'product_cat'); if (is_array($cats) && !empty($cats)) { foreach ($cats as $cat) { $categories .= $cat->name . ', '; } $categories = rtrim($categories, ', '); } } $reps = array_merge($reps, array($order_id, $order_date, $order_datetime, $email_data['first_name'], $email_data['first_name'] . ' ' . $email_data['last_name'], $email_data['email_to'], $renew_date, $days_to_renew, '<a href="' . $item_url . '">' . get_the_title($item_id) . '</a>', $categories)); } return $reps; }
/** * Check if a payment is being made on a failed renewal order from 'My Account'. If so, * redirect the order into a cart/checkout payment flow. * * @since 1.3 */ public static function before_woocommerce_pay() { global $woocommerce, $wp; if (isset($_GET['pay_for_order']) && (isset($_GET['order']) && isset($_GET['order_id']) || isset($_GET['key']) && isset($wp->query_vars['order-pay']))) { // Pay for existing order $order_key = isset($_GET['key']) ? $_GET['key'] : $_GET['order']; // WC 2.1 compatibility $order_id = isset($wp->query_vars['order-pay']) ? $wp->query_vars['order-pay'] : absint($_GET['order_id']); $order = new WC_Order($order_id); $failed_order_replaced_by = get_post_meta($order_id, '_failed_order_replaced_by', true); if (is_numeric($failed_order_replaced_by)) { WC_Subscriptions::add_notice(sprintf(__('Sorry, this failed order has already been paid. See order %s.', 'woocommerce-subscriptions'), $failed_order_replaced_by), 'error'); wp_safe_redirect(get_permalink(woocommerce_get_page_id('myaccount'))); exit; } if ($order->id == $order_id && $order->order_key == $order_key && in_array($order->status, array('pending', 'failed')) && WC_Subscriptions_Renewal_Order::is_renewal($order)) { // If order being paid is a parent order, get the original order, else query parent_order if (WC_Subscriptions_Renewal_Order::is_renewal($order_id, array('order_role' => 'parent'))) { $role = 'parent'; $original_order = new WC_Order(WC_Subscriptions_Order::get_meta($order, 'original_order', false)); } elseif (WC_Subscriptions_Renewal_Order::is_renewal($order_id, array('order_role' => 'child'))) { $role = 'child'; $original_order = WC_Subscriptions_Renewal_Order::get_parent_order($order_id); } $order_items = WC_Subscriptions_Order::get_recurring_items($original_order); $first_order_item = reset($order_items); $product_id = WC_Subscriptions_Order::get_items_product_id($first_order_item); $product = get_product($product_id); $variation_id = ''; $variation_data = array(); // Display error message for deleted products if (false === $product) { WC_Subscriptions::add_notice(self::$product_deleted_error_message, 'error'); // Make sure we don't actually need the variation ID } elseif ($product->is_type(array('variable-subscription'))) { $item = WC_Subscriptions_Order::get_item_by_product_id($original_order, $product_id); $variation_id = $item['variation_id']; $variation = get_product($variation_id); // Display error message for deleted product variations if (false === $variation) { WC_Subscriptions::add_notice(self::$product_deleted_error_message, 'error'); $variation_data = array(); } else { $variation_data = $variation->get_variation_attributes(); } } elseif ($product->is_type(array('subscription_variation'))) { // Handle existing renewal orders incorrectly using variation_id as the product_id $product_id = $product->id; $variation_id = $product->get_variation_id(); $variation_data = $product->get_variation_attributes(); } $woocommerce->cart->empty_cart(true); $woocommerce->cart->add_to_cart($product_id, 1, $variation_id, $variation_data, array('subscription_renewal' => array('original_order' => $original_order->id, 'failed_order' => $order_id, 'role' => $role))); wp_safe_redirect($woocommerce->cart->get_checkout_url()); exit; } } }
/** * get_content_plain function. * * @access public * @return string */ function get_content_plain() { $order = new WC_Order($this->object['order_id']); $item_name = WC_Subscriptions_Order::get_item_name($this->object['order_id'], $this->object['product_id']); $order_item = WC_Subscriptions_Order::get_item_by_product_id($order, $this->object['product_id']); $product = $order->get_product_from_item($order_item); if (isset($product->variation_data)) { $item_name .= ' (' . woocommerce_get_formatted_variation($product->variation_data, true) . ')'; } WC_Subscriptions_Order::$recurring_only_price_strings = true; $recurring_total = WC_Subscriptions_Order::get_formatted_order_total(0, $order); WC_Subscriptions_Order::$recurring_only_price_strings = false; if ($end_of_prepaid_term = wp_next_scheduled('scheduled_subscription_end_of_prepaid_term', array('user_id' => (int) $order->user_id, 'subscription_key' => $this->subscription_key))) { $end_of_prepaid_term = date_i18n(woocommerce_date_format(), $end_of_prepaid_term + get_option('gmt_offset') * 3600); } ob_start(); woocommerce_get_template($this->template_plain, array('subscription_key' => $this->subscription_key, 'subscription' => $this->object, 'order' => $order, 'email_heading' => $this->get_heading(), 'item_name' => $item_name, 'recurring_total' => $recurring_total, 'last_payment' => date_i18n(woocommerce_date_format(), WC_Subscriptions_Manager::get_last_payment_date($this->subscription_key, '', 'timestamp')), 'end_of_prepaid_term' => $end_of_prepaid_term), '', $this->template_base); return ob_get_clean(); }
function woo_ce_get_subscription_order_item( $order_id = 0, $product_id = 0 ) { if( method_exists( 'WC_Subscriptions_Order', 'get_item_by_product_id' ) ) $order_item = WC_Subscriptions_Order::get_item_by_product_id( $order_id, $product_id ); return $order_item; }
/** * Handles the display of builder sections. */ public function get_builder_display($field, $where, $args, $form_prefix = "", $product_id = 0) { /* $form_prefix shoud be passed with _ if not empty */ $columns = array("w25" => array("col-3", 25), "w33" => array("col-4", 33), "w50" => array("col-6", 50), "w66" => array("col-8", 66), "w75" => array("col-9", 75), "w100" => array("col-12", 100)); extract($args, EXTR_OVERWRITE); if (isset($field['sections']) && is_array($field['sections'])) { $args = array('field_id' => 'tm-epo-field-' . $unit_counter); wc_get_template('tm-builder-start.php', $args, $this->_namespace, $this->template_path); $_section_totals = 0; foreach ($field['sections'] as $section) { if (!isset($section['sections_placement']) || $section['sections_placement'] != $where) { continue; } if (isset($section['sections_size']) && isset($columns[$section['sections_size']])) { $size = $columns[$section['sections_size']][0]; } else { $size = "col-12"; } $_section_totals = $_section_totals + $columns[$section['sections_size']][1]; if ($_section_totals > 100) { $_section_totals = $columns[$section['sections_size']][1]; echo '<div class="cpfclear"></div>'; } $divider = ""; if (isset($section['divider_type'])) { switch ($section['divider_type']) { case "hr": $divider = '<hr>'; break; case "divider": $divider = '<div class="tm_divider"></div>'; break; case "padding": $divider = '<div class="tm_padding"></div>'; break; } } $label_size = 'h3'; if (!empty($section['label_size'])) { switch ($section['label_size']) { case "1": $label_size = 'h1'; break; case "2": $label_size = 'h2'; break; case "3": $label_size = 'h3'; break; case "4": $label_size = 'h4'; break; case "5": $label_size = 'h5'; break; case "6": $label_size = 'h6'; break; case "7": $label_size = 'p'; break; case "8": $label_size = 'div'; break; case "9": $label_size = 'span'; break; } } $args = array('column' => $size, 'style' => $section['sections_style'], 'uniqid' => $section['sections_uniqid'], 'logic' => esc_html(json_encode((array) json_decode($section['sections_clogic']))), 'haslogic' => $section['sections_logic'], 'sections_class' => $section['sections_class'], 'sections_type' => $section['sections_type'], 'title_size' => $label_size, 'title' => !empty($section['label']) ? $section['label'] : "", 'title_color' => !empty($section['label_color']) ? $section['label_color'] : "", 'description' => !empty($section['description']) ? $section['description'] : "", 'description_color' => !empty($section['description_color']) ? $section['description_color'] : "", 'description_position' => !empty($section['description_position']) ? $section['description_position'] : "", 'divider' => $divider); // custom variations check if (isset($section['elements']) && is_array($section['elements']) && isset($section['elements'][0]) && is_array($section['elements'][0]) && isset($section['elements'][0]['type']) && $section['elements'][0]['type'] == 'variations') { $args['sections_class'] = $args['sections_class'] . " tm-epo-variation-section"; } wc_get_template('tm-builder-section-start.php', $args, $this->_namespace, $this->template_path); if (isset($section['elements']) && is_array($section['elements'])) { $totals = 0; $slide_counter = 0; $use_slides = false; $doing_slides = false; if ($section['sections_slides'] !== "" && $section['sections_type'] == "slider") { $sections_slides = explode(",", $section['sections_slides']); $use_slides = true; } foreach ($section['elements'] as $element) { $empty_rules = ""; if (isset($element['rules_filtered'])) { $empty_rules = esc_html(json_encode($element['rules_filtered'])); } $empty_rules_type = ""; if (isset($element['rules_type'])) { $empty_rules_type = esc_html(json_encode($element['rules_type'])); } if (isset($element['size']) && isset($columns[$element['size']])) { $size = $columns[$element['size']][0]; } else { $size = "col-12"; } $test_for_first_slide = false; if ($use_slides && isset($sections_slides[$slide_counter])) { $sections_slides[$slide_counter] = intval($sections_slides[$slide_counter]); if ($sections_slides[$slide_counter] > 0 && !$doing_slides) { echo '<div class="tm-slide">'; $doing_slides = true; $test_for_first_slide = true; } } $fee_name = $this->fee_name; $cart_fee_name = $this->cart_fee_name; $totals = $totals + $columns[$element['size']][1]; if ($totals > 100 && !$test_for_first_slide) { $totals = $columns[$element['size']][1]; echo '<div class="cpfclear"></div>'; } $divider = ""; if (isset($element['divider_type'])) { $divider_class = ""; if ($element['type'] == 'divider' && !empty($element['class'])) { $divider_class = " " . $element['class']; } switch ($element['divider_type']) { case "hr": $divider = '<hr' . $divider_class . '>'; break; case "divider": $divider = '<div class="tm_divider' . $divider_class . '"></div>'; break; case "padding": $divider = '<div class="tm_padding' . $divider_class . '"></div>'; break; } } $label_size = 'h3'; if (!empty($element['label_size'])) { switch ($element['label_size']) { case "1": $label_size = 'h1'; break; case "2": $label_size = 'h2'; break; case "3": $label_size = 'h3'; break; case "4": $label_size = 'h4'; break; case "5": $label_size = 'h5'; break; case "6": $label_size = 'h6'; break; case "7": $label_size = 'p'; break; case "8": $label_size = 'div'; break; case "9": $label_size = 'span'; break; case "10": $label_size = 'label'; break; } } $variations_builder_element_start_args = array(); $tm_validation = $this->get_tm_validation_rules($element); $args = array('tm_element_settings' => $element, 'column' => $size, 'class' => !empty($element['class']) ? $element['class'] : "", 'title_size' => $label_size, 'title' => !empty($element['label']) ? $element['label'] : "", 'title_position' => !empty($element['label_position']) ? $element['label_position'] : "", 'title_color' => !empty($element['label_color']) ? $element['label_color'] : "", 'description' => !empty($element['description']) ? $element['description'] : "", 'description_color' => !empty($element['description_color']) ? $element['description_color'] : "", 'description_position' => !empty($element['description_position']) ? $element['description_position'] : "", 'divider' => $divider, 'required' => $element['required'], 'type' => $element['type'], 'use_images' => $element['use_images'], 'use_url' => $element['use_url'], 'rules' => $empty_rules, 'rules_type' => $empty_rules_type, 'element' => $element['type'], 'class_id' => "tm-element-ul-" . $element['type'] . " element_" . $element_counter . $form_prefix, 'uniqid' => $element['uniqid'], 'logic' => esc_html(json_encode((array) json_decode($element['clogic']))), 'haslogic' => $element['logic'], 'clear_options' => empty($element['clear_options']) ? "" : $element['clear_options'], 'exactlimit' => empty($element['exactlimit']) ? "" : 'tm-exactlimit', 'minimumlimit' => empty($element['minimumlimit']) ? "" : 'tm-minimumlimit', 'tm_validation' => esc_html(json_encode($tm_validation))); if ($element['type'] != "variations") { wc_get_template('tm-builder-element-start.php', $args, $this->_namespace, $this->template_path); } else { $variations_builder_element_start_args = $args; } $field_counter = 0; $init_class = "TM_EPO_FIELDS_" . $element['type']; if (!class_exists($init_class) && !empty($this->tm_builder_elements[$element['type']]["_is_addon"])) { $init_class = "TM_EPO_FIELDS"; } if (isset($this->tm_builder_elements[$element['type']]) && ($this->tm_builder_elements[$element['type']]["is_post"] == "post" || $this->tm_builder_elements[$element['type']]["is_post"] == "display") && class_exists($init_class)) { $field_obj = new $init_class(); if ($this->tm_builder_elements[$element['type']]["is_post"] == "post") { if ($this->tm_builder_elements[$element['type']]["type"] == "single" || $this->tm_builder_elements[$element['type']]["type"] == "multiplesingle") { $tabindex++; $name_inc = $this->tm_builder_elements[$element['type']]["post_name_prefix"] . "_" . $element_counter . $form_prefix; if ($this->tm_builder_elements[$element['type']]["type"] == "single") { $is_fee = !empty($element['rules_type']) && $element['rules_type'][0][0] == "subscriptionfee"; $is_cart_fee = !empty($element['rules_type']) && isset($element['rules_type'][0]) && isset($element['rules_type'][0][0]) && $element['rules_type'][0][0] == "fee"; } elseif ($this->tm_builder_elements[$element['type']]["type"] == "multiplesingle") { $is_fee = !empty($element['selectbox_fee']) && $element['selectbox_fee'][0][0] == "subscriptionfee"; $is_cart_fee = !empty($element['selectbox_cart_fee']) && $element['selectbox_cart_fee'][0][0] == "fee"; } if ($is_fee) { $name_inc = $fee_name . $name_inc; } elseif ($is_cart_fee) { $name_inc = $cart_fee_name . $name_inc; } if (isset($_GET['switch-subscription']) && (function_exists('wcs_get_subscription') || class_exists('WC_Subscriptions_Manager') && class_exists('WC_Subscriptions_Order'))) { $item = false; if (function_exists('wcs_get_subscription')) { $subscription = wcs_get_subscription($_GET['switch-subscription']); if ($subscription instanceof WC_Subscription) { $original_order = new WC_Order($subscription->order->id); $item = WC_Subscriptions_Order::get_item_by_product_id($original_order, $subscription->id); } } else { $subscription = WC_Subscriptions_Manager::get_subscription($_GET['switch-subscription']); $original_order = new WC_Order($subscription['order_id']); $item = WC_Subscriptions_Order::get_item_by_product_id($original_order, $subscription['product_id']); } if ($item) { $saved_data = maybe_unserialize($item["item_meta"]["_tmcartepo_data"][0]); foreach ($saved_data as $key => $val) { if (isset($val["key"])) { if ($element['uniqid'] == $val["section"]) { $_GET['tmcp_' . $name_inc] = $val["key"]; if (isset($val['quantity'])) { $_GET['tmcp_' . $name_inc . '_quantity'] = $val['quantity']; } } } else { if ($element['uniqid'] == $val["section"]) { $_GET['tmcp_' . $name_inc] = $val["value"]; if (isset($val['quantity'])) { $_GET['tmcp_' . $name_inc . '_quantity'] = $val['quantity']; } } } } } } elseif (!empty($this->cart_edit_key) && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'tm-edit')) { $_cart = WC()->cart; if (isset($_cart->cart_contents) && isset($_cart->cart_contents[$this->cart_edit_key])) { if (!empty($_cart->cart_contents[$this->cart_edit_key]['tmcartepo'])) { $saved_epos = $_cart->cart_contents[$this->cart_edit_key]['tmcartepo']; foreach ($saved_epos as $key => $val) { if (isset($val["key"])) { if ($element['uniqid'] == $val["section"]) { $_GET['tmcp_' . $name_inc] = $val["key"]; if (isset($val['quantity'])) { $_GET['tmcp_' . $name_inc . '_quantity'] = $val['quantity']; } } } else { if ($element['uniqid'] == $val["section"]) { $_GET['tmcp_' . $name_inc] = $val["value"]; if (isset($val['quantity'])) { $_GET['tmcp_' . $name_inc . '_quantity'] = $val['quantity']; } } } } } if (!empty($_cart->cart_contents[$this->cart_edit_key]['tmcartfee'])) { $saved_fees = $_cart->cart_contents[$this->cart_edit_key]['tmcartfee']; foreach ($saved_fees as $key => $val) { if (isset($val["key"])) { if ($element['uniqid'] == $val["section"]) { $_GET['tmcp_' . $name_inc] = $val["key"]; if (isset($val['quantity'])) { $_GET['tmcp_' . $name_inc . '_quantity'] = $val['quantity']; } } } else { if ($element['uniqid'] == $val["section"]) { $_GET['tmcp_' . $name_inc] = $val["value"]; if (isset($val['quantity'])) { $_GET['tmcp_' . $name_inc . '_quantity'] = $val['quantity']; } } } } } if (!empty($_cart->cart_contents[$this->cart_edit_key]['tmsubscriptionfee'])) { $saved_subscriptionfees = $_cart->cart_contents[$this->cart_edit_key]['tmsubscriptionfee']; foreach ($saved_subscriptionfees as $key => $val) { if (isset($val["key"])) { if ($element['uniqid'] == $val["section"]) { $_GET['tmcp_' . $name_inc] = $val["key"]; if (isset($val['quantity'])) { $_GET['tmcp_' . $name_inc . '_quantity'] = $val['quantity']; } } } else { if ($element['uniqid'] == $val["section"]) { $_GET['tmcp_' . $name_inc] = $val["value"]; if (isset($val['quantity'])) { $_GET['tmcp_' . $name_inc . '_quantity'] = $val['quantity']; } } } } } } } $display = $field_obj->display_field($element, array('name_inc' => $name_inc, 'element_counter' => $element_counter, 'tabindex' => $tabindex, 'form_prefix' => $form_prefix, 'field_counter' => $field_counter)); if (is_array($display)) { $args = array('tm_element_settings' => $element, 'id' => 'tmcp_' . $this->tm_builder_elements[$element['type']]["post_name_prefix"] . '_' . $tabindex . $form_prefix, 'name' => 'tmcp_' . $name_inc, 'class' => !empty($element['class']) ? $element['class'] : "", 'tabindex' => $tabindex, 'rules' => isset($element['rules_filtered']) ? esc_html(json_encode($element['rules_filtered'])) : '', 'rules_type' => isset($element['rules_type']) ? esc_html(json_encode($element['rules_type'])) : '', 'amount' => '0 ' . $_currency, 'fieldtype' => $is_fee ? $this->fee_name_class : ($is_cart_fee ? $this->cart_fee_class : "tmcp-field"), 'field_counter' => $field_counter); $args = array_merge($args, $display); if ($this->tm_builder_elements[$element['type']]["_is_addon"]) { do_action("tm_epo_display_addons", $element, $args, array('name_inc' => $name_inc, 'element_counter' => $element_counter, 'tabindex' => $tabindex, 'form_prefix' => $form_prefix, 'field_counter' => $field_counter), $this->tm_builder_elements[$element['type']]["namespace"]); } elseif (is_readable($this->template_path . 'tm-' . $element['type'] . '.php')) { wc_get_template('tm-' . $element['type'] . '.php', $args, $this->_namespace, $this->template_path); } } } elseif ($this->tm_builder_elements[$element['type']]["type"] == "multipleall" || $this->tm_builder_elements[$element['type']]["type"] == "multiple") { $field_obj->display_field_pre($element, array('element_counter' => $element_counter, 'tabindex' => $tabindex, 'form_prefix' => $form_prefix, 'field_counter' => $field_counter, 'product_id' => isset($product_id) ? $product_id : 0)); foreach ($element['options'] as $value => $label) { $tabindex++; if ($this->tm_builder_elements[$element['type']]["type"] == "multipleall") { $name_inc = $this->tm_builder_elements[$element['type']]["post_name_prefix"] . "_" . $element_counter . "_" . $field_counter . $form_prefix; } else { $name_inc = $this->tm_builder_elements[$element['type']]["post_name_prefix"] . "_" . $element_counter . $form_prefix; } $is_fee = isset($element['rules_type'][$value]) && $element['rules_type'][$value][0] == "subscriptionfee"; $is_cart_fee = isset($element['rules_type'][$value]) && $element['rules_type'][$value][0] == "fee"; if ($is_fee) { $name_inc = $fee_name . $name_inc; } elseif ($is_cart_fee) { $name_inc = $cart_fee_name . $name_inc; } $display = $field_obj->display_field($element, array('name_inc' => $name_inc, 'value' => $value, 'label' => $label, 'element_counter' => $element_counter, 'tabindex' => $tabindex, 'form_prefix' => $form_prefix, 'field_counter' => $field_counter)); if (is_array($display)) { $args = array('tm_element_settings' => $element, 'id' => 'tmcp_' . $this->tm_builder_elements[$element['type']]["post_name_prefix"] . '_' . $element_counter . "_" . $field_counter . "_" . $tabindex . $form_prefix, 'name' => 'tmcp_' . $name_inc, 'class' => !empty($element['class']) ? $element['class'] : "", 'tabindex' => $tabindex, 'rules' => isset($element['rules_filtered'][$value]) ? esc_html(json_encode($element['rules_filtered'][$value])) : '', 'rules_type' => isset($element['rules_type'][$value]) ? esc_html(json_encode($element['rules_type'][$value])) : '', 'amount' => '0 ' . $_currency, 'fieldtype' => $is_fee ? $this->fee_name_class : ($is_cart_fee ? $this->cart_fee_class : "tmcp-field"), 'border_type' => $this->tm_epo_css_selected_border, 'field_counter' => $field_counter); $args = array_merge($args, $display); if (isset($_GET['switch-subscription']) && (function_exists('wcs_get_subscription') || class_exists('WC_Subscriptions_Manager') && class_exists('WC_Subscriptions_Order'))) { $item = false; if (function_exists('wcs_get_subscription')) { $subscription = wcs_get_subscription($_GET['switch-subscription']); if ($subscription instanceof WC_Subscription) { $original_order = new WC_Order($subscription->order->id); $item = WC_Subscriptions_Order::get_item_by_product_id($original_order, $subscription->id); } } else { $subscription = WC_Subscriptions_Manager::get_subscription($_GET['switch-subscription']); $original_order = new WC_Order($subscription['order_id']); $item = WC_Subscriptions_Order::get_item_by_product_id($original_order, $subscription['product_id']); } if ($item) { $saved_data = maybe_unserialize($item["item_meta"]["_tmcartepo_data"][0]); foreach ($saved_data as $key => $val) { if ($element['uniqid'] == $val["section"] && $args["value"] == $val["key"]) { $_GET[$args['name']] = $val["key"]; if (isset($val['quantity'])) { $_GET[$args['name'] . '_quantity'] = $val['quantity']; } } } } } elseif (!empty($this->cart_edit_key) && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'tm-edit')) { //add_filter('woocommerce_product_single_add_to_cart_text',array($this,'tm_woocommerce_product_single_add_to_cart_text'),9999); $_cart = WC()->cart; if (isset($_cart->cart_contents) && isset($_cart->cart_contents[$this->cart_edit_key])) { if (!empty($_cart->cart_contents[$this->cart_edit_key]['tmcartepo'])) { $saved_epos = $_cart->cart_contents[$this->cart_edit_key]['tmcartepo']; foreach ($saved_epos as $key => $val) { if ($element['uniqid'] == $val["section"] && $args["value"] == $val["key"]) { $_GET[$args['name']] = $val["key"]; if (isset($val['quantity'])) { $_GET[$args['name'] . '_quantity'] = $val['quantity']; } } } } if (!empty($_cart->cart_contents[$this->cart_edit_key]['tmcartfee'])) { $saved_fees = $_cart->cart_contents[$this->cart_edit_key]['tmcartfee']; foreach ($saved_fees as $key => $val) { if ($element['uniqid'] == $val["section"] && $args["value"] == $val["key"]) { $_GET[$args['name']] = $val["key"]; if (isset($val['quantity'])) { $_GET[$args['name'] . '_quantity'] = $val['quantity']; } } } } if (!empty($_cart->cart_contents[$this->cart_edit_key]['tmsubscriptionfee'])) { $saved_subscriptionfees = $_cart->cart_contents[$this->cart_edit_key]['tmsubscriptionfee']; foreach ($saved_subscriptionfees as $key => $val) { if ($element['uniqid'] == $val["section"] && $args["value"] == $val["key"]) { $_GET[$args['name']] = $val["key"]; if (isset($val['quantity'])) { $_GET[$args['name'] . '_quantity'] = $val['quantity']; } } } } } } if ($this->tm_builder_elements[$element['type']]["_is_addon"]) { do_action("tm_epo_display_addons", $element, $args, array('name_inc' => $name_inc, 'element_counter' => $element_counter, 'tabindex' => $tabindex, 'form_prefix' => $form_prefix, 'field_counter' => $field_counter, 'border_type' => $this->tm_epo_css_selected_border), $this->tm_builder_elements[$element['type']]["namespace"]); } elseif (is_readable($this->template_path . 'tm-' . $element['type'] . '.php')) { wc_get_template('tm-' . $element['type'] . '.php', $args, $this->_namespace, $this->template_path); } } $field_counter++; } } $element_counter++; } elseif ($this->tm_builder_elements[$element['type']]["is_post"] == "display") { $display = $field_obj->display_field($element, array('element_counter' => $element_counter, 'tabindex' => $tabindex, 'form_prefix' => $form_prefix, 'field_counter' => $field_counter)); if (is_array($display)) { $args = array('tm_element_settings' => $element, 'class' => !empty($element['class']) ? $element['class'] : "", 'form_prefix' => $form_prefix, 'field_counter' => $field_counter, 'tm_element' => $element, 'tm__namespace' => $this->_namespace, 'tm_template_path' => $this->template_path, 'tm_product_id' => $product_id); if ($element['type'] == "variations") { $args["variations_builder_element_start_args"] = $variations_builder_element_start_args; $args["variations_builder_element_end_args"] = array('tm_element_settings' => $element, 'element' => $element['type'], 'description' => !empty($element['description']) ? $element['description'] : "", 'description_color' => !empty($element['description_color']) ? $element['description_color'] : "", 'description_position' => !empty($element['description_position']) ? $element['description_position'] : ""); } $args = array_merge($args, $display); if ($this->tm_builder_elements[$element['type']]["_is_addon"]) { do_action("tm_epo_display_addons", $element, $args, array('name_inc' => '', 'element_counter' => $element_counter, 'tabindex' => $tabindex, 'form_prefix' => $form_prefix, 'field_counter' => $field_counter), $this->tm_builder_elements[$element['type']]["namespace"]); } elseif (is_readable($this->template_path . 'tm-' . $element['type'] . '.php')) { wc_get_template('tm-' . $element['type'] . '.php', $args, $this->_namespace, $this->template_path); } } } unset($field_obj); // clear memory } if ($element['type'] != "variations") { wc_get_template('tm-builder-element-end.php', array('tm_element_settings' => $element, 'element' => $element['type'], 'description' => !empty($element['description']) ? $element['description'] : "", 'description_color' => !empty($element['description_color']) ? $element['description_color'] : "", 'description_position' => !empty($element['description_position']) ? $element['description_position'] : ""), $this->_namespace, $this->template_path); } if ($use_slides && isset($sections_slides[$slide_counter])) { $sections_slides[$slide_counter] = $sections_slides[$slide_counter] - 1; if ($sections_slides[$slide_counter] <= 0) { echo '</div>'; $slide_counter++; $doing_slides = false; } } } } $args = array('column' => $size, 'style' => $section['sections_style'], 'sections_type' => $section['sections_type']); wc_get_template('tm-builder-section-end.php', $args, $this->_namespace, $this->template_path); } wc_get_template('tm-builder-end.php', array(), $this->_namespace, $this->template_path); $unit_counter++; } return array('tabindex' => $tabindex, 'unit_counter' => $unit_counter, 'field_counter' => $field_counter, 'element_counter' => $element_counter, '_currency' => $_currency); }
public function email_replacements($reps, $email_data, $email_order, $email_row) { global $wpdb, $woocommerce; $email_type = $email_row->email_type; $order_date = ''; $order_datetime = ''; $order_id = ''; if ($email_order->order_id) { $order = WC_FUE_Compatibility::wc_get_order($email_order->order_id); $order_date = date(get_option('date_format'), strtotime($order->order_date)); $order_datetime = date(get_option('date_format') . ' ' . get_option('time_format'), strtotime($order->order_date)); $order_id = apply_filters('woocommerce_order_number', '#' . $email_order->order_id, $order); $billing_address = $order->get_formatted_billing_address(); $shipping_address = $order->get_formatted_shipping_address(); $item = WC_Subscriptions_Order::get_item_by_product_id($order); $item_id = WC_Subscriptions_Order::get_items_product_id($item); $renewal = self::calculate_next_payment_timestamp($order, $item_id); $subs_key = WC_Subscriptions_Manager::get_subscription_key($email_order->order_id, $item_id); $renew_date = date(get_option('date_format'), $renewal); $end_date = WC_Subscriptions_Manager::get_subscription_expiration_date($subs_key, '', 'timestamp'); if ($end_date == 0) { $end_date = __('Until Cancelled', 'follow_up_emails'); } else { $end_date = date(get_option('date_format'), $end_date); } // calc days to renew $now = current_time('timestamp'); $diff = $renewal - $now; $days_to_renew = 0; if ($diff > 0) { $days_to_renew = floor($diff / 86400); } $item_url = FUE_Sending_Mailer::create_email_url($email_order->id, $email_row->id, $email_data['user_id'], $email_data['email_to'], get_permalink($item_id)); $categories = ''; if ($item_id) { $cats = get_the_terms($item_id, 'product_cat'); if (is_array($cats) && !empty($cats)) { foreach ($cats as $cat) { $categories .= $cat->name . ', '; } $categories = rtrim($categories, ', '); } } $reps = array_merge($reps, array($order_id, $order_date, $order_datetime, $billing_address, $shipping_address, $email_data['username'], $email_data['first_name'], $email_data['first_name'] . ' ' . $email_data['last_name'], $email_data['email_to'], $renew_date, $end_date, $days_to_renew, '<a href="' . $item_url . '">' . get_the_title($item_id) . '</a>', $categories)); } return $reps; }
/** * When a store manager or user reactivates a subscription in the store, also reactivate the subscription with PayPal. * * How PayPal Handles suspension is discussed here: https://www.x.com/developers/paypal/forums/nvp/reactivate-recurring-profile * * @since 1.1 */ public static function reactivate_subscription_with_paypal($order, $product_id) { $profile_id = self::get_subscriptions_paypal_id($order, $product_id); // Make sure a subscriptions status is active with PayPal $response = self::change_subscription_status($profile_id, 'Reactivate'); $item = WC_Subscriptions_Order::get_item_by_product_id($order, $product_id); if (isset($response['ACK']) && $response['ACK'] == 'Success') { $order->add_order_note(sprintf(__('Subscription "%s" reactivated with PayPal', WC_Subscriptions::$text_domain), $item['name'])); } }
/** * Processes a failed payment on a subscription by recording the failed payment and cancelling the subscription if it exceeds the * maximum number of failed payments allowed on the site. * * @param $user_id int The id of the user who owns the expiring subscription. * @param $subscription_key string A subscription key of the form obtained by @see get_subscription_key( $order_id, $product_id ) * @since 1.0 */ public static function process_subscription_payment_failure($user_id, $subscription_key) { // Store a record of the subscription payment date $subscription = self::get_users_subscription($user_id, $subscription_key); if (!isset($subscription['failed_payments'])) { $subscription['failed_payments'] = 0; } $subscription['failed_payments'] = $subscription['failed_payments'] + 1; self::update_users_subscriptions($user_id, array($subscription_key => $subscription)); $order = new WC_Order($subscription['order_id']); $item = WC_Subscriptions_Order::get_item_by_product_id($order, $subscription['product_id']); $max_failed_payments = get_option(WC_Subscriptions_Admin::$option_prefix . '_max_failed_payments', 3); // Allow a short circuit for plugins & payment gateways to force max failed payments exceeded $failed_payments_exceeded = apply_filters('woocommerce_subscriptions_max_failed_payments_exceeded', false, $user_id, $subscription_key); // Have we reached the maximum failed payments allowed on the subscription if ($failed_payments_exceeded || $subscription['failed_payments'] >= $max_failed_payments && intval($max_failed_payments) !== 0) { self::cancel_subscription($user_id, $subscription_key); $order->add_order_note(sprintf(__('Cancelled Subscription "%s". Maximum number of failed subscription payments reached.', WC_Subscriptions::$text_domain), $item['name'])); if ('yes' == get_option(WC_Subscriptions_Admin::$option_prefix . '_generate_renewal_order')) { $renewal_order_id = WC_Subscriptions_Renewal_Order::generate_renewal_order($order, $subscription['product_id'], array('new_order_role' => 'parent')); } } else { // Log payment failure on order $order->add_order_note(sprintf(__('Payment failed for subscription "%s".', WC_Subscriptions::$text_domain), $item['name'])); // Place the subscription on-hold self::put_subscription_on_hold($user_id, $subscription_key); } do_action('processed_subscription_payment_failure', $user_id, $subscription_key); }
"> <?php } ?> <?php echo WC_Subscriptions_Order::get_item_name($subscription_details['order_id'], $subscription_details['product_id']); ?> <?php if (false !== $product) { ?> </a> <?php } ?> <?php $order_item = WC_Subscriptions_Order::get_item_by_product_id($order, $subscription_details['product_id']); ?> <?php if (WC_Subscriptions::is_woocommerce_pre('2.4')) { ?> <?php $item_meta = new WC_Order_Item_Meta($order_item['item_meta'], $product); ?> <?php } else { ?> <?php $item_meta = new WC_Order_Item_Meta($order_item, $product); ?> <?php }
public function replace_variables($text, $email_order) { $order = new WC_Order($email_order->order_id); $item = WC_Subscriptions_Order::get_item_by_product_id($order); $item_id = WC_Subscriptions_Order::get_items_product_id($item); $renewal = WC_Subscriptions_Order::get_next_payment_timestamp($order, $item_id); $renew_date = date(get_option('date_format'), $renewal); // calc days to renew $now = current_time('timestamp'); $diff = $renewal - $now; $days_to_renew = 0; if ($diff > 0) { $days_to_renew = floor($diff / 86400); } $search = array('{subs_renew_date}', '{days_to_renew}'); $replacements = array($renew_date, $days_to_renew); return str_replace($search, $replacements, $text); }
/** * Get, sort and filter subscriptions for display. * * @uses $this->_column_headers * @uses $this->items * @uses $this->get_columns() * @uses $this->get_sortable_columns() * @uses $this->get_pagenum() * @uses $this->set_pagination_args() * @since 1.0 */ function prepare_items() { $screen = get_current_screen(); $per_page = $this->get_items_per_page($screen->get_option('per_page', 'option'), 10); $this->get_column_info(); $this->process_actions(); if (isset($_REQUEST['s'])) { $subscriptions_grouped_by_user = WC_Subscriptions_Manager::search_subscriptions($_REQUEST['s']); } elseif (isset($_GET['_customer_user']) || isset($_GET['_product_id'])) { if (isset($_GET['_customer_user']) && !empty($_GET['_customer_user'])) { $subscriptions_grouped_by_user = array($_GET['_customer_user'] => WC_Subscriptions_Manager::get_users_subscriptions($_GET['_customer_user'])); } else { $subscriptions_grouped_by_user = WC_Subscriptions_Manager::get_all_users_subscriptions(); } if (isset($_GET['_product_id']) && !empty($_GET['_product_id'])) { foreach ($subscriptions_grouped_by_user as $user_id => $subscriptions) { foreach ($subscriptions as $subscription_key => $subscription) { if ($subscription['product_id'] == intval($_GET['_product_id'])) { continue; } $order_item = WC_Subscriptions_Order::get_item_by_product_id($subscription['order_id'], $subscription['product_id']); if (isset($order_item['variation_id']) && $order_item['variation_id'] == intval($_GET['_product_id'])) { continue; } unset($subscriptions_grouped_by_user[$user_id][$subscription_key]); } } } } else { $subscriptions_grouped_by_user = WC_Subscriptions_Manager::get_all_users_subscriptions(); } $status_to_show = isset($_GET['status']) ? $_GET['status'] : 'all'; // Reformat the subscriptions grouped by user to be usable by each row $subscriptions = array(); $this->statuses = array(); foreach ($subscriptions_grouped_by_user as $user_id => $users_subscriptions) { foreach ($users_subscriptions as $subscription_key => $subscription) { $this->statuses[$subscription['status']] = isset($this->statuses[$subscription['status']]) ? $this->statuses[$subscription['status']] + 1 : 1; $all_subscriptions[$subscription_key] = $subscription + array('user_id' => $user_id, 'subscription_key' => $subscription_key); if ($status_to_show == $subscription['status'] || $status_to_show == 'all' && $subscription['status'] != 'trash') { $subscriptions[$subscription_key] = $subscription + array('user_id' => $user_id, 'subscription_key' => $subscription_key); } } } // If we have a request for a status that does not exist, default to all subscriptions if (!isset($this->statuses[$status_to_show])) { if ($status_to_show != 'all') { $status_to_show = $_GET['status'] = 'all'; foreach ($all_subscriptions as $subscription_key => $subscription) { if ($all_subscriptions[$subscription_key]['status'] != 'trash') { $subscriptions = $subscriptions + array($subscription_key => $subscription); } } } else { $_GET['status'] = 'all'; } } ksort($this->statuses); $this->statuses = array('all' => array_sum($this->statuses)) + $this->statuses; if (isset($this->statuses['trash'])) { $this->statuses['all'] = $this->statuses['all'] - $this->statuses['trash']; } usort($subscriptions, array(&$this, 'sort_subscriptions')); // Add sorted & sliced data to the items property to be used by the rest of the class $this->items = array_slice($subscriptions, ($this->get_pagenum() - 1) * $per_page, $per_page); $total_items = count($subscriptions); $this->set_pagination_args(array('total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => ceil($total_items / $per_page))); }
function wc_subs_exporter_create_csv($export) { global $wc_subs_exporter; if (!$export->status) { return false; } if (empty($export->subscriptions)) { return false; } $subscription_statuses = wc_subs_exporter_get_subscription_statuses(); $fields = array(__('Order Id', 'wc-subs-exporter'), __('Order Status', 'wc-subs-exporter'), __('Subscription Status', 'wc-subs-exporter'), __('Subscription Description', 'wc-subs-exporter'), __('Subscription Start Date', 'wc-subs-exporter'), __('Subscription Expiration Date', 'wc-subs-exporter'), __('Subscription Last Payment', 'wc-subs-exporter'), __('Email', 'wc-subs-exporter'), __('Billing First Name', 'wc-subs-exporter'), __('Billing Last Name', 'wc-subs-exporter'), __('Billing Address 1', 'wc-subs-exporter'), __('Billing Address 2', 'wc-subs-exporter'), __('Billing City', 'wc-subs-exporter'), __('Billing State', 'wc-subs-exporter'), __('Billing Zip', 'wc-subs-exporter'), __('Billing Country', 'wc-subs-exporter'), __('Shipping First Name', 'wc-subs-exporter'), __('Shipping Last Name', 'wc-subs-exporter'), __('Shipping Address 1', 'wc-subs-exporter'), __('Shipping Address 2', 'wc-subs-exporter'), __('Shipping City', 'wc-subs-exporter'), __('Shipping State', 'wc-subs-exporter'), __('Shipping Zip', 'wc-subs-exporter'), __('Shipping Country', 'wc-subs-exporter'), __('Product SKU', 'wc-subs-exporter'), __('Product Description', 'wc-subs-exporter'), __('Quantity', 'wc-subs-exporter'), __('Date Ordered', 'wc-subs-exporter'), __('Coupon Code Used', 'wc-subs-exporter')); $csv = ''; if ($export->bom) { $csv .= chr(239) . chr(187) . chr(191) . ''; } foreach ($fields as $field) { $csv .= wc_subs_exporter_escape_csv_value($field, $export->delimiter, $export->escape_formatting) . $export->delimiter; } $csv = substr($csv, 0, -strlen($export->delimiter)) . "\n"; $processed_rows = 0; foreach ($export->subscriptions as $user => $user_subscriptions) { foreach ($user_subscriptions as $key => $subscription) { $order = new WC_Order($subscription['order_id']); $order_item = WC_Subscriptions_Order::get_item_by_product_id($order, $subscription['product_id']); $product = $order->get_product_from_item($order_item); if (empty($product)) { continue; } $product_sku = $product->get_sku(); $product_title = WC_Subscriptions_Order::get_item_name($subscription['order_id'], $subscription['product_id']); if (isset($product->variation_data)) { $product_description = woocommerce_get_formatted_variation($product->variation_data, true); } else { $product_description = $product_title; } $coupon_code_used = ''; $coupons = $order->get_items(array('coupon')); foreach ($coupons as $item_id => $item) { $coupon_code_used .= $item['name'] . ' '; } $start_date = substr($subscription['start_date'], 0, 10); if ($subscription['expiry_date']) { $end_date = substr($subscription['expiry_date'], 0, 10); } else { $end_date = '0000-00-00'; } if ($order->user_id > 0) { $user_info = get_userdata($order->user_id); } if (array_key_exists('completed_payments', $subscription) && is_array($subscription['completed_payments'])) { $recent_payment = substr(end($subscription['completed_payments']), 0, 10); } else { $recent_payment = ''; } $order_date = substr($order->completed_date, 0, 10); $csv .= wc_subs_exporter_escape_csv_value($order->id, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->status, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($subscription_statuses[$subscription['status']], $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($product_title, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($start_date, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($end_date, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($recent_payment, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($user_info->user_email, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->billing_first_name, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->billing_last_name, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->billing_address_1, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->billing_address_2, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->billing_city, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->billing_state, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->billing_postcode, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->billing_country, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->shipping_first_name, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->shipping_last_name, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->shipping_address_1, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->shipping_address_2, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->shipping_city, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->shipping_state, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->shipping_postcode, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order->shipping_country, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($product_sku, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($product_description, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value(1, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value($order_date, $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= wc_subs_exporter_escape_csv_value(trim($coupon_code_used), $export->delimiter, $export->escape_formatting) . $export->delimiter; $csv .= "\n"; } } if (!$csv) { return false; } else { if (isset($wc_subs_exporter['debug']) && $wc_subs_exporter['debug']) { $wc_subs_exporter['debug_log'] = $csv; } else { return $csv; } } }
/** * Processes a failed payment on a subscription by recording the failed payment and cancelling the subscription if it exceeds the * maximum number of failed payments allowed on the site. * * @param int $user_id The id of the user who owns the expiring subscription. * @param string $subscription_key A subscription key of the form obtained by @see get_subscription_key( $order_id, $product_id ) * @since 1.0 */ public static function process_subscription_payment_failure($user_id, $subscription_key) { // Store a record of the subscription payment date $subscription = self::get_subscription($subscription_key); if (!isset($subscription['failed_payments'])) { $subscription['failed_payments'] = 0; } $subscription['failed_payments'] = $subscription['failed_payments'] + 1; self::update_users_subscriptions($user_id, array($subscription_key => $subscription)); $order = new WC_Order($subscription['order_id']); $item = WC_Subscriptions_Order::get_item_by_product_id($order, $subscription['product_id']); // Allow a short circuit for plugins & payment gateways to force max failed payments exceeded if (apply_filters('woocommerce_subscriptions_max_failed_payments_exceeded', false, $user_id, $subscription_key)) { self::cancel_subscription($user_id, $subscription_key); $order->add_order_note(sprintf(__('Cancelled Subscription "%s". Maximum number of failed subscription payments reached.', 'woocommerce-subscriptions'), $item['name'])); $renewal_order_id = WC_Subscriptions_Renewal_Order::generate_renewal_order($order, $subscription['product_id'], array('new_order_role' => 'parent')); } else { // Log payment failure on order $order->add_order_note(sprintf(__('Payment failed for subscription "%s".', 'woocommerce-subscriptions'), $item['name'])); // Place the subscription on-hold self::put_subscription_on_hold($user_id, $subscription_key); } do_action('processed_subscription_payment_failure', $user_id, $subscription_key); }
/** * Callback for the [subscriptions] shortcode that displays subscription names for a particular user. * * @param array $attributes Shortcode attributes. * @return string */ public static function do_subscriptions_shortcode($attributes) { $attributes = wp_parse_args($attributes, array('user_id' => 0, 'status' => 'active')); $status = $attributes['status']; $subscriptions = WC_Subscriptions_Manager::get_users_subscriptions($attributes['user_id']); if (empty($subscriptions)) { return '<ul class="user-subscriptions no-user-subscriptions"> <li>No subscriptions found.</li> </ul>'; } $list = '<ul class="user-subscriptions">'; foreach ($subscriptions as $subscription) { if ($subscription['status'] == $status || $status == 'all') { $subscription_details = WC_Subscriptions_Order::get_item_name($subscription['order_id'], $subscription['product_id']); $order = new WC_Order($subscription['order_id']); $order_item = WC_Subscriptions_Order::get_item_by_product_id($subscription['order_id'], $subscription['product_id']); $product = $order->get_product_from_item($order_item); if (isset($product->variation_data)) { $subscription_details .= ' <span class="subscription-variation-data">(' . woocommerce_get_formatted_variation($product->variation_data, true) . ')</span>'; } $list .= sprintf('<li>%s</li>', $subscription_details); } } $list .= '</ul>'; return $list; }
/** * Outputs the content for each column. * * @param array $item A singular item (one full row's worth of data) * @param array $column_name The name/slug of the column to be processed * @return string Text or HTML to be placed inside the column <td> * @since 1.0 */ public function column_default($item, $column_name) { global $woocommerce; $current_gmt_time = gmdate('U'); $column_content = ''; switch ($column_name) { case 'status': $actions = array(); $action_url = add_query_arg(array('page' => $_REQUEST['page'], 'user' => $item['user_id'], 'subscription' => $item['subscription_key'], '_wpnonce' => wp_create_nonce($item['subscription_key']))); if (isset($_REQUEST['status'])) { $action_url = add_query_arg(array('status' => $_REQUEST['status']), $action_url); } $order = new WC_Order($item['order_id']); $all_statuses = array('active' => __('Reactivate', 'woocommerce-subscriptions'), 'on-hold' => __('Suspend', 'woocommerce-subscriptions'), 'cancelled' => __('Cancel', 'woocommerce-subscriptions'), 'trash' => __('Trash', 'woocommerce-subscriptions'), 'deleted' => __('Delete Permanently', 'woocommerce-subscriptions')); foreach ($all_statuses as $status => $label) { if (WC_Subscriptions_Manager::can_subscription_be_changed_to($status, $item['subscription_key'], $item['user_id'])) { $action = 'deleted' == $status ? 'delete' : $status; // For built in CSS $actions[$action] = sprintf('<a href="%s">%s</a>', esc_url(add_query_arg('new_status', $status, $action_url)), $label); } } if ($item['status'] == 'pending') { unset($actions['active']); unset($actions['trash']); } elseif (!in_array($item['status'], array('cancelled', 'expired', 'switched', 'suspended'))) { unset($actions['trash']); } $actions = apply_filters('woocommerce_subscriptions_list_table_actions', $actions, $item); $column_content = sprintf('<mark class="%s">%s</mark> %s', sanitize_title($item[$column_name]), WC_Subscriptions_Manager::get_status_to_display($item[$column_name], $item['subscription_key'], $item['user_id']), $this->row_actions($actions)); $column_content = apply_filters('woocommerce_subscriptions_list_table_column_status_content', $column_content, $item, $actions, $this); break; case 'title': //Return the title contents $column_content = sprintf('<a href="%s">%s</a>', get_edit_post_link($item['product_id']), WC_Subscriptions_Order::get_item_name($item['order_id'], $item['product_id'])); $order = new WC_Order($item['order_id']); $order_item = WC_Subscriptions_Order::get_item_by_product_id($order, $item['product_id']); $product = $order->get_product_from_item($order_item); if (isset($product->variation_data)) { $column_content .= '<br />' . woocommerce_get_formatted_variation($product->variation_data, true); } break; case 'order_id': $order = new WC_Order($item[$column_name]); $column_content = sprintf('<a href="%1$s">%2$s</a>', get_edit_post_link($item[$column_name]), sprintf(__('Order %s', 'woocommerce-subscriptions'), $order->get_order_number())); break; case 'user': $user = get_user_by('id', $item['user_id']); if (is_object($user)) { $column_content = sprintf('<a href="%s">%s</a>', admin_url('user-edit.php?user_id=' . $user->ID), ucfirst($user->display_name)); } break; case 'start_date': case 'expiry_date': case 'end_date': if ($column_name == 'expiry_date' && $item[$column_name] == 0) { $column_content = __('Never', 'woocommerce-subscriptions'); } else { if ($column_name == 'end_date' && $item[$column_name] == 0) { $column_content = __('Not yet ended', 'woocommerce-subscriptions'); } else { $gmt_timestamp = strtotime($item[$column_name]); $user_timestamp = $gmt_timestamp + get_option('gmt_offset') * 3600; $column_content = sprintf('<time>%s</time>', date_i18n(woocommerce_date_format(), $user_timestamp)); } } break; case 'trial_expiry_date': $trial_expiration = WC_Subscriptions_Manager::get_trial_expiration_date($item['subscription_key'], $item['user_id'], 'timestamp'); if (empty($trial_expiration)) { $column_content = '-'; } else { $column_content = sprintf('<time title="%s">%s</time>', esc_attr($trial_expiration), date_i18n(woocommerce_date_format(), $trial_expiration + get_option('gmt_offset') * 3600)); } break; case 'last_payment_date': // Although we record the sign-up date as a payment, if there is a free trial and no sign-up fee, no payment is actually charged if (0 == WC_Subscriptions_Order::get_total_initial_payment($item['order_id']) && 1 == count($item['completed_payments'])) { $column_content = '-'; } else { $last_payment_timestamp = strtotime($item['last_payment_date']); $time_diff = $current_gmt_time - $last_payment_timestamp; if ($time_diff > 0 && $time_diff < 7 * 24 * 60 * 60) { $last_payment = sprintf(__('%s ago', 'woocommerce-subscriptions'), human_time_diff($last_payment_timestamp, $current_gmt_time)); } else { $last_payment = date_i18n(woocommerce_date_format(), $last_payment_timestamp + get_option('gmt_offset') * 3600); } $column_content = sprintf('<time title="%s">%s</time>', esc_attr($last_payment_timestamp), $last_payment); } break; case 'next_payment_date': $next_payment_timestamp_gmt = WC_Subscriptions_Manager::get_next_payment_date($item['subscription_key'], $item['user_id'], 'timestamp'); $next_payment_timestamp = $next_payment_timestamp_gmt + get_option('gmt_offset') * 3600; if ($next_payment_timestamp_gmt == 0) { $column_content = '-'; } else { // Convert to site time $time_diff = $next_payment_timestamp_gmt - $current_gmt_time; if ($time_diff > 0 && $time_diff < 7 * 24 * 60 * 60) { $next_payment = sprintf(__('In %s', 'woocommerce-subscriptions'), human_time_diff($current_gmt_time, $next_payment_timestamp_gmt)); } else { $next_payment = date_i18n(woocommerce_date_format(), $next_payment_timestamp); } $column_content = sprintf('<time class="next-payment-date" title="%s">%s</time>', esc_attr($next_payment_timestamp), $next_payment); if (WC_Subscriptions_Manager::can_subscription_be_changed_to('new-payment-date', $item['subscription_key'], $item['user_id'])) { $column_content .= '<div class="edit-date-div row-actions hide-if-no-js">'; $column_content .= '<img class="date-picker-icon" src="' . admin_url('images/date-button.gif') . '" title="' . __('Date Picker Icon', 'woocommerce-subscriptions') . '" />'; $column_content .= '<a href="#edit_timestamp" class="edit-timestamp" tabindex="4">' . __('Change', 'woocommerce-subscriptions') . '</a>'; $column_content .= '<div class="date-picker-div hide-if-js">'; $column_content .= WC_Subscriptions_Manager::touch_time(array('date' => date('Y-m-d', $next_payment_timestamp), 'echo' => false, 'multiple' => true, 'include_time' => false)); $column_content .= '</div>'; $column_content .= '</div>'; } } break; case 'renewal_order_count': $count = WC_Subscriptions_Renewal_Order::get_renewal_order_count($item['order_id']); $column_content = sprintf('<a href="%1$s">%2$d</a>', admin_url('edit.php?post_status=all&post_type=shop_order&_renewal_order_parent_id=' . absint($item['order_id'])), $count); break; } return apply_filters('woocommerce_subscriptions_list_table_column_content', $column_content, $item, $column_name); }
/** * Check if a payment is being made on a failed renewal order from 'My Account'. If so, * redirect the order into a cart/checkout payment flow. * * @since 1.3 */ public static function before_woocommerce_pay() { global $woocommerce; if (isset($_GET['pay_for_order']) && isset($_GET['order']) && isset($_GET['order_id'])) { // Pay for existing order $order_key = urldecode($_GET['order']); $order_id = absint($_GET['order_id']); $order = new WC_Order($order_id); $failed_order_replaced_by = get_post_meta($order_id, '_failed_order_replaced_by', true); if (is_numeric($failed_order_replaced_by)) { $woocommerce->add_error(sprintf(__('Sorry, this failed order has already been paid. See order %s.', WC_Subscriptions::$text_domain), $failed_order_replaced_by)); wp_safe_redirect(get_permalink(woocommerce_get_page_id('myaccount'))); exit; } if ($order->id == $order_id && $order->order_key == $order_key && in_array($order->status, array('pending', 'failed')) && WC_Subscriptions_Renewal_Order::is_renewal($order)) { // If order being paid is a parent order, get the original order, else query parent_order if (WC_Subscriptions_Renewal_Order::is_renewal($order_id, array('order_role' => 'parent'))) { $role = 'parent'; $original_order = new WC_Order($order->order_custom_fields['_original_order'][0]); } elseif (WC_Subscriptions_Renewal_Order::is_renewal($order_id, array('order_role' => 'child'))) { $role = 'child'; $original_order = WC_Subscriptions_Renewal_Order::get_parent_order($order_id); } $order_items = WC_Subscriptions_Order::get_recurring_items($original_order); $first_order_item = reset($order_items); $product_id = WC_Subscriptions_Order::get_items_product_id($first_order_item); $product = get_product($product_id); // Make sure we don't actually need the variation ID if ($product->is_type(array('variable-subscription'))) { $item = WC_Subscriptions_Order::get_item_by_product_id($original_order, $product_id); $variation_id = $item['variation_id']; $variation = get_product($variation_id); $variation_data = $variation->get_variation_attributes(); } elseif ($product->is_type(array('subscription_variation'))) { // Handle existing renewal orders incorrectly using variation_id as the product_id $product_id = $product->id; $variation_id = $product->get_variation_id(); $variation_data = $product->get_variation_attributes(); } else { $variation_id = ''; $variation_data = array(); } $woocommerce->cart->empty_cart(true); $woocommerce->cart->add_to_cart($product_id, 1, $variation_id, $variation_data, array('subscription_renewal' => array('original_order' => $original_order->id, 'failed_order' => $order_id, 'role' => $role))); wp_safe_redirect($woocommerce->cart->get_checkout_url()); exit; } } }
/** * Renders a table with subscription information. * @param array $options * @param int $n will be set to the number of subscriptions found */ public static function render($options, &$n) { global $wpdb; $output = ''; if (isset($options['user_id'])) { $user = new WP_User($options['user_id']); } else { return $output; } $statuses = array('active'); $show_all = false; if (isset($options['status'])) { $status = $options['status']; if (is_string($status)) { if (trim($status) === '*') { $statuses = array('active', 'on-hold', 'cancelled', 'trash', 'deleted', 'switched'); } else { $statuses = array(); $_statuses = explode(',', $status); foreach ($_statuses as $status) { $status = strtolower(trim($status)); switch ($status) { case 'active': case 'on-hold': case 'cancelled': case 'trash': case 'deleted': case 'switched': $statuses[] = $status; break; } } } } } $exclude_cancelled_after_end_of_prepaid_term = isset($options['exclude_cancelled_after_end_of_prepaid_term']) && ($options['exclude_cancelled_after_end_of_prepaid_term'] === true || $options['exclude_cancelled_after_end_of_prepaid_term'] == 'true' || $options['exclude_cancelled_after_end_of_prepaid_term'] == 'yes'); $include_cancelled_orders = isset($options['include_cancelled_orders']) && ($options['include_cancelled_orders'] === true || $options['include_cancelled_orders'] == 'true' || $options['include_cancelled_orders'] == 'yes'); $include_refunded_orders = isset($options['include_refunded_orders']) && ($options['include_refunded_orders'] === true || $options['include_refunded_orders'] == 'true' || $options['include_refunded_orders'] == 'yes'); if (function_exists('wcs_get_users_subscriptions')) { $results = array(); foreach (wcs_get_users_subscriptions($user->ID) as $subscription) { $results[wcs_get_old_subscription_key($subscription)] = wcs_get_subscription_in_deprecated_structure($subscription); } } else { $results = WC_Subscriptions_Manager::get_users_subscriptions($user->ID); } // pre-filter by status $_results = array(); foreach ($results as $result_key => $result) { $valid = false; if (in_array($result['status'], $statuses)) { $valid = true; } // exclude subscriptions from cancelled or refunded orders if (isset($result['order_id'])) { if ($order = Groups_WS_Helper::get_order($result['order_id'])) { switch ($order->status) { case 'cancelled': if (!$include_cancelled_orders) { $valid = false; } break; case 'refunded': if (!$include_refunded_orders) { $valid = false; } break; } } } if ($exclude_cancelled_after_end_of_prepaid_term && $result['status'] == 'cancelled') { $hook_args = array('user_id' => (int) $user->ID, 'subscription_key' => $result_key); $end_timestamp = wp_next_scheduled('scheduled_subscription_end_of_prepaid_term', $hook_args); if ($end_timestamp === false || $end_timestamp <= time()) { $valid = false; } } if ($valid) { $_results[$result_key] = $result; } } $results = $_results; $n = count($results); if ($n > 0) { $column_display_names = array('status' => __('Status', GROUPS_WS_PLUGIN_DOMAIN), 'title' => __('Subscription', GROUPS_WS_PLUGIN_DOMAIN), 'start_date' => __('Start Date', GROUPS_WS_PLUGIN_DOMAIN), 'expiry_date' => __('Expiration', GROUPS_WS_PLUGIN_DOMAIN), 'end_date' => __('End Date', GROUPS_WS_PLUGIN_DOMAIN), 'trial_expiry_date' => __('Trial Expiration', GROUPS_WS_PLUGIN_DOMAIN), 'groups' => __('Groups', GROUPS_WS_PLUGIN_DOMAIN), 'order_id' => __('Order', GROUPS_WS_PLUGIN_DOMAIN)); if (isset($options['columns']) && $options['columns'] !== null) { if (is_string($options['columns'])) { $columns = explode(',', $options['columns']); $_columns = array(); foreach ($columns as $column) { $_columns[] = trim($column); } $options['columns'] = $_columns; } $new_columns = array(); foreach ($options['columns'] as $key) { if (key_exists($key, $column_display_names)) { $new_columns[$key] = $column_display_names[$key]; } } $column_display_names = $new_columns; } if (count($column_display_names) > 0) { $output .= '<table class="subscriptions">'; $output .= '<thead>'; $output .= '<tr>'; foreach ($column_display_names as $key => $column_display_name) { $output .= "<th scope='col' class='{$key}'>{$column_display_name}</th>"; } $output .= '</tr>'; $output .= '</thead>'; $output .= '<tbody>'; $i = 0; foreach ($results as $result_key => $result) { $order = Groups_WS_Helper::get_order($result['order_id']); if ($order) { $order_item = WC_Subscriptions_Order::get_item_by_product_id($order, $result['product_id']); $product = $order->get_product_from_item($order_item); $output .= '<tr class="' . ($i % 2 == 0 ? 'even' : 'odd') . '">'; foreach ($column_display_names as $column_key => $column_title) { $output .= sprintf('<td class="%s">', $column_key); switch ($column_key) { case 'status': $output .= WC_Subscriptions_Manager::get_status_to_display($result['status'], $result_key, $user->ID); break; case 'title': $output .= WC_Subscriptions_Order::get_item_name($result['order_id'], $result['product_id']); if (isset($product->variation_data)) { $column_content .= '<br />'; if (function_exists('wc_get_formatted_variation')) { $column_content .= wc_get_formatted_variation($product->variation_data, true); } else { $column_content .= woocommerce_get_formatted_variation($product->variation_data, true); } } break; case 'start_date': case 'expiry_date': case 'end_date': if ($column_key == 'expiry_date' && $result[$column_key] == 0) { $output .= __('Never', GROUPS_WS_PLUGIN_DOMAIN); } else { if ($column_key == 'end_date' && $result[$column_key] == 0) { $output .= __('Not yet ended', GROUPS_WS_PLUGIN_DOMAIN); } else { $user_timestamp = strtotime($result[$column_key]) + get_option('gmt_offset') * 3600; $output .= sprintf('<time title="%s">%s</time>', esc_attr($user_timestamp), date_i18n(get_option('date_format'), $user_timestamp)); } } break; case 'trial_expiry_date': $trial_expiration = WC_Subscriptions_Manager::get_trial_expiration_date($result_key, $user->ID, 'timestamp'); if (empty($trial_expiration)) { $output .= '-'; } else { $trial_expiration = $trial_expiration + get_option('gmt_offset') * 3600; $output .= sprintf('<time title="%s">%s</time>', esc_attr($trial_expiration), date_i18n(get_option('date_format'), $trial_expiration)); } break; case 'groups': if ($product_groups = get_post_meta($result['product_id'], '_groups_groups', false)) { if (count($product_groups) > 0) { $output .= '<ul>'; foreach ($product_groups as $group_id) { if ($group = Groups_Group::read($group_id)) { $output .= '<li>' . wp_filter_nohtml_kses($group->name) . '</li>'; } } $output .= '</ul>'; } } break; case 'order_id': $output .= sprintf(__('Order %d', GROUPS_WS_PLUGIN_DOMAIN), $result['order_id']); break; } $output .= '</td>'; } $output .= '</tr>'; $i++; } } $output .= '</tbody>'; $output .= '</table>'; } } return $output; }