* @var WP_POST $variation * @var string $subscription_period * @var array $variation_data array of variation data */ if (!defined('ABSPATH')) { exit; } global $wp_locale; ?> <tr class="variable_subscription_sync show_if_variable-subscription"> <td colspan="1" class="subscription_sync_week_month"<?php echo $display_week_month_select; ?> > <?php if (WC_Subscriptions::is_woocommerce_pre_2_3()) { ?> <label><?php _e('Synchronise Renewals', 'woocommerce-subscriptions'); ?> </label> <?php } woocommerce_wp_select(array('id' => 'variable' . WC_Subscriptions_Synchroniser::$post_meta_key . '[' . $loop . ']', 'class' => 'wc_input_subscription_payment_sync', 'wrapper_class' => '_subscription_payment_sync_field', 'label' => WC_Subscriptions_Synchroniser::$sync_field_label, 'options' => WC_Subscriptions_Synchroniser::get_billing_period_ranges($subscription_period), 'description' => WC_Subscriptions_Synchroniser::$sync_description, 'desc_tip' => true, 'value' => $payment_day)); ?> </td> <td colspan="1" class="subscription_sync_annual"<?php echo $display_annual_select; ?> > <label><?php
/** * If the order is a renewal order, don't send core emails. * * @param int $user_id The ID of the user who the subscription belongs to * @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key() * @return void */ public static function maybe_reattach_woocommerce_email($order_id) { global $woocommerce; if (WC_Subscriptions_Renewal_Order::is_renewal($order_id, array('order_role' => 'child')) || WC_Subscriptions_Switcher::order_contains_subscription_switch($order_id)) { if (WC_Subscriptions::is_woocommerce_pre_2_3()) { add_action(current_filter(), array($woocommerce, 'send_transactional_email')); } else { add_action(current_filter(), array('WC_Emails', 'send_transactional_email')); } } }
/** * When creating an order at checkout, if the order is for renewing a subscription from a failed * payment, hijack the order creation to make a renewal order - not a vanilla WooCommerce order. * * @since 1.3 */ public static function filter_woocommerce_create_order($order_id, $checkout_object) { global $woocommerce; $cart_item = WC_Subscriptions_Cart::cart_contains_subscription_renewal(); if ($cart_item && 'child' == $cart_item['subscription_renewal']['role']) { $product_id = $cart_item['product_id']; $failed_order_id = $cart_item['subscription_renewal']['failed_order']; $original_order_id = $cart_item['subscription_renewal']['original_order']; $role = $cart_item['subscription_renewal']['role']; $renewal_order_args = array('new_order_role' => $role, 'checkout_renewal' => true, 'failed_order_id' => $failed_order_id); $renewal_order_id = WC_Subscriptions_Renewal_Order::generate_renewal_order($original_order_id, $product_id, $renewal_order_args); $original_order = new WC_Order($original_order_id); $customer_id = $original_order->customer_user; // Save posted billing address fields to both renewal and original order if ($checkout_object->checkout_fields['billing']) { foreach ($checkout_object->checkout_fields['billing'] as $key => $field) { update_post_meta($renewal_order_id, '_' . $key, $checkout_object->posted[$key]); update_post_meta($original_order->id, '_' . $key, $checkout_object->posted[$key]); // User if ($customer_id && !empty($checkout_object->posted[$key])) { update_user_meta($customer_id, $key, $checkout_object->posted[$key]); // Special fields switch ($key) { case "billing_email": if (!email_exists($checkout_object->posted[$key])) { wp_update_user(array('ID' => $customer_id, 'user_email' => $checkout_object->posted[$key])); } break; case "billing_first_name": wp_update_user(array('ID' => $customer_id, 'first_name' => $checkout_object->posted[$key])); break; case "billing_last_name": wp_update_user(array('ID' => $customer_id, 'last_name' => $checkout_object->posted[$key])); break; } } } } // Save posted shipping address fields to both renewal and original order if ($checkout_object->checkout_fields['shipping'] && ($woocommerce->cart->needs_shipping() || get_option('woocommerce_require_shipping_address') == 'yes')) { foreach ($checkout_object->checkout_fields['shipping'] as $key => $field) { $postvalue = false; if (isset($checkout_object->posted['shiptobilling']) && $checkout_object->posted['shiptobilling'] || isset($checkout_object->posted['ship_to_different_address']) && $checkout_object->posted['ship_to_different_address']) { if (isset($checkout_object->posted[str_replace('shipping_', 'billing_', $key)])) { $postvalue = $checkout_object->posted[str_replace('shipping_', 'billing_', $key)]; update_post_meta($renewal_order_id, '_' . $key, $postvalue); update_post_meta($original_order->id, '_' . $key, $postvalue); } } elseif (isset($checkout_object->posted[$key])) { $postvalue = $checkout_object->posted[$key]; update_post_meta($renewal_order_id, '_' . $key, $postvalue); update_post_meta($original_order->id, '_' . $key, $postvalue); } // User if ($postvalue && $customer_id) { update_user_meta($customer_id, $key, $postvalue); } } } if ($checkout_object->posted['payment_method']) { $available_gateways = $woocommerce->payment_gateways->get_available_payment_gateways(); if (isset($available_gateways[$checkout_object->posted['payment_method']])) { $payment_method = $available_gateways[$checkout_object->posted['payment_method']]; $payment_method->validate_fields(); update_post_meta($renewal_order_id, '_payment_method', $payment_method->id); update_post_meta($renewal_order_id, '_payment_method_title', $payment_method->get_title()); } } // Set the shipping method for WC < 2.1 if ($checkout_object->posted['shipping_method'] && method_exists($woocommerce->shipping, 'get_available_shipping_methods')) { $available_shipping_methods = $woocommerce->shipping->get_available_shipping_methods(); if (isset($available_shipping_methods[$checkout_object->posted['shipping_method']])) { $shipping_method = $available_shipping_methods[$checkout_object->posted['shipping_method']]; update_post_meta($renewal_order_id, '_shipping_method', $shipping_method->id); update_post_meta($renewal_order_id, '_shipping_method_title', $shipping_method->label); } } if (isset($failed_order_id)) { $failed_order = new WC_Order($failed_order_id); if ($failed_order->status == 'failed') { update_post_meta($failed_order_id, '_failed_order_replaced_by', $renewal_order_id); } } // Store fees, any new fees on this order should be applied now foreach ($woocommerce->cart->get_fees() as $fee) { $item_id = woocommerce_add_order_item($renewal_order_id, array('order_item_name' => $fee->name, 'order_item_type' => 'fee')); if ($fee->taxable) { woocommerce_add_order_item_meta($item_id, '_tax_class', $fee->tax_class); } else { woocommerce_add_order_item_meta($item_id, '_tax_class', '0'); } woocommerce_add_order_item_meta($item_id, '_line_total', woocommerce_format_decimal($fee->amount)); woocommerce_add_order_item_meta($item_id, '_line_tax', woocommerce_format_decimal($fee->tax)); } // Store tax rows foreach (array_keys($woocommerce->cart->taxes + $woocommerce->cart->shipping_taxes) as $key) { $item_id = woocommerce_add_order_item($renewal_order_id, array('order_item_name' => WC_Tax::get_rate_code($key), 'order_item_type' => 'tax')); // Add line item meta if ($item_id) { woocommerce_add_order_item_meta($item_id, 'rate_id', $key); woocommerce_add_order_item_meta($item_id, 'label', WC_Tax::get_rate_label($key)); woocommerce_add_order_item_meta($item_id, 'compound', absint(WC_Tax::is_compound($key) ? 1 : 0)); woocommerce_add_order_item_meta($item_id, 'tax_amount', woocommerce_format_decimal(isset($woocommerce->cart->taxes[$key]) ? $woocommerce->cart->taxes[$key] : 0)); woocommerce_add_order_item_meta($item_id, 'shipping_tax_amount', woocommerce_format_decimal(isset($woocommerce->cart->shipping_taxes[$key]) ? $woocommerce->cart->shipping_taxes[$key] : 0)); } } // Store shipping for all packages on this order (as this can differ between each order), WC 2.1 if (method_exists($woocommerce->shipping, 'get_packages')) { $packages = $woocommerce->shipping->get_packages(); foreach ($packages as $i => $package) { if (isset($package['rates'][$checkout_object->shipping_methods[$i]])) { $method = $package['rates'][$checkout_object->shipping_methods[$i]]; $item_id = woocommerce_add_order_item($renewal_order_id, array('order_item_name' => $method->label, 'order_item_type' => 'shipping')); if ($item_id) { woocommerce_add_order_item_meta($item_id, 'method_id', $method->id); woocommerce_add_order_item_meta($item_id, 'cost', woocommerce_format_decimal($method->cost)); do_action('woocommerce_add_shipping_order_item', $renewal_order_id, $item_id, $i); } } } } update_post_meta($renewal_order_id, '_order_shipping', WC_Subscriptions::format_total($woocommerce->cart->shipping_total)); update_post_meta($renewal_order_id, '_cart_discount', WC_Subscriptions::format_total($woocommerce->cart->get_cart_discount_total())); update_post_meta($renewal_order_id, '_order_tax', WC_Subscriptions::format_total($woocommerce->cart->tax_total)); update_post_meta($renewal_order_id, '_order_shipping_tax', WC_Subscriptions::format_total($woocommerce->cart->shipping_tax_total)); update_post_meta($renewal_order_id, '_order_total', WC_Subscriptions::format_total($woocommerce->cart->total)); // WC < 2.3, set deprecated after tax discount total if (WC_Subscriptions::is_woocommerce_pre_2_3()) { update_post_meta($renewal_order_id, '_order_discount', WC_Subscriptions::format_total($woocommerce->cart->get_total_discount())); } update_post_meta($renewal_order_id, '_order_currency', get_woocommerce_currency()); update_post_meta($renewal_order_id, '_prices_include_tax', get_option('woocommerce_prices_include_tax')); update_post_meta($renewal_order_id, '_customer_ip_address', isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']); update_post_meta($renewal_order_id, '_customer_user_agent', isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''); update_post_meta($renewal_order_id, '_checkout_renewal', 'yes'); // Return the new order's ID to prevent WC creating an order $order_id = $renewal_order_id; } return $order_id; }
/** * Add the sync setting fields to the variation section of the Edit Product screen * * @since 1.5 */ public static function variable_subscription_product_fields($loop, $variation_data, $variation) { if (self::is_syncing_enabled()) { // Set month as the default billing period if (!($subscription_period = get_post_meta($variation->ID, '_subscription_period', true))) { $subscription_period = 'month'; } $display_week_month_select = !in_array($subscription_period, array('month', 'week')) ? ' style="display: none;"' : ''; $display_annual_select = 'year' != $subscription_period ? ' style="display: none;"' : ''; $payment_day = self::get_products_payment_day($variation->ID); // An annual sync date is already set in the form: array( 'day' => 'nn', 'month' => 'nn' ), create a MySQL string from those values (year and time are irrelvent as they are ignored) if (is_array($payment_day)) { $payment_month = $payment_day['month']; $payment_day = $payment_day['day']; } else { $payment_month = date('m'); } if (WC_Subscriptions::is_woocommerce_pre_2_3()) { include plugin_dir_path(WC_Subscriptions::$plugin_file) . 'templates/admin/deprecated/html-variation-synchronisation.php'; } else { include plugin_dir_path(WC_Subscriptions::$plugin_file) . 'templates/admin/html-variation-synchronisation.php'; } } }
/** * Adds all necessary admin styles. * * @param array Array of Product types & their labels, excluding the Subscription product type. * @return array Array of Product types & their labels, including the Subscription product type. * @since 1.0 */ public static function enqueue_styles_scripts() { global $woocommerce, $post; // Get admin screen id $screen = get_current_screen(); $is_woocommerce_screen = in_array($screen->id, array('product', 'edit-shop_order', 'shop_order', self::$admin_screen_id, 'users', 'woocommerce_page_wc-settings')) ? true : false; $is_activation_screen = get_transient(WC_Subscriptions::$activation_transient) == true ? true : false; if ($is_woocommerce_screen) { $dependencies = array('jquery'); // Version juggling if (WC_Subscriptions::is_woocommerce_pre_2_1()) { // WC 2.0 $woocommerce_admin_script_handle = 'woocommerce_writepanel'; } elseif (WC_Subscriptions::is_woocommerce_pre_2_2()) { // WC 2.1 $woocommerce_admin_script_handle = 'woocommerce_admin_meta_boxes'; } else { $woocommerce_admin_script_handle = 'wc-admin-meta-boxes'; } if ($screen->id == 'product') { $dependencies[] = $woocommerce_admin_script_handle; if (!WC_Subscriptions::is_woocommerce_pre_2_2()) { $dependencies[] = 'wc-admin-product-meta-boxes'; $dependencies[] = 'wc-admin-variation-meta-boxes'; } $script_params = array('productType' => WC_Subscriptions::$name, 'trialPeriodSingular' => WC_Subscriptions_Manager::get_available_time_periods(), 'trialPeriodPlurals' => WC_Subscriptions_Manager::get_available_time_periods('plural'), 'subscriptionLengths' => WC_Subscriptions_Manager::get_subscription_ranges(), 'trialTooLongMessages' => self::get_trial_period_validation_message('separate'), 'bulkEditPeriodMessage' => __('Enter the new period, either day, week, month or year:', 'woocommerce-subscriptions'), 'bulkEditLengthMessage' => __('Enter a new length (e.g. 5):', 'woocommerce-subscriptions'), 'bulkEditIntervalhMessage' => __('Enter a new interval as a single number (e.g. to charge every 2nd month, enter 2):', 'woocommerce-subscriptions')); } else { if ('edit-shop_order' == $screen->id) { $script_params = array('bulkTrashWarning' => __("You are about to trash one or more orders which contain a subscription.\n\nTrashing the orders will also trash the subscriptions purchased with these orders.", 'woocommerce-subscriptions')); } else { if ('shop_order' == $screen->id) { $dependencies[] = $woocommerce_admin_script_handle; if (!WC_Subscriptions::is_woocommerce_pre_2_2()) { $dependencies[] = 'wc-admin-order-meta-boxes'; $dependencies[] = 'wc-admin-order-meta-boxes-modal'; } $script_params = array('bulkTrashWarning' => __('Trashing this order will also trash the subscription purchased with the order.', 'woocommerce-subscriptions'), 'changeMetaWarning' => __("WARNING: Bad things are about to happen!\n\nThe payment gateway used to purchase this subscription does not support modifying a subscription's details.\n\nChanges to the billing period, recurring discount, recurring tax or recurring total may not be reflected in the amount charged by the payment gateway.", 'woocommerce-subscriptions'), 'removeItemWarning' => __("You are deleting a subscription item. You will also need to manually cancel and trash the subscription on the Manage Subscriptions screen.", 'woocommerce-subscriptions'), 'roundAtSubtotal' => esc_attr(get_option('woocommerce_tax_round_at_subtotal')), 'EditOrderNonce' => wp_create_nonce('woocommerce-subscriptions'), 'postId' => $post->ID); } else { if ('users' == $screen->id) { $dependencies[] = 'ajax-chosen'; $script_params = array('deleteUserWarning' => __("WARNING: Deleting a user will also remove them from any subscription.", 'woocommerce-subscriptions')); } else { if (self::$admin_screen_id == $screen->id) { $dependencies[] = 'ajax-chosen'; $script_params = array('ajaxDateChangeNonce' => wp_create_nonce('woocommerce-subscriptions'), 'searchCustomersNonce' => wp_create_nonce('search-customers'), 'searchCustomersLabel' => __('Show all customers', 'woocommerce-subscriptions'), 'searchProductsNonce' => wp_create_nonce('search-products')); } } } } } $script_params['ajaxLoaderImage'] = $woocommerce->plugin_url() . '/assets/images/ajax-loader.gif'; $script_params['ajaxUrl'] = admin_url('admin-ajax.php'); $script_params['isWCPre21'] = var_export(WC_Subscriptions::is_woocommerce_pre_2_1(), true); $script_params['isWCPre22'] = var_export(WC_Subscriptions::is_woocommerce_pre_2_2(), true); $script_params['isWCPre23'] = var_export(WC_Subscriptions::is_woocommerce_pre_2_3(), true); wp_enqueue_script('woocommerce_subscriptions_admin', plugin_dir_url(WC_Subscriptions::$plugin_file) . 'js/admin.js', $dependencies, filemtime(plugin_dir_path(WC_Subscriptions::$plugin_file) . 'js/admin.js')); wp_localize_script('woocommerce_subscriptions_admin', 'WCSubscriptions', apply_filters('woocommerce_subscriptions_admin_script_parameters', $script_params)); // Maybe add the pointers for first timers if (isset($_GET['subscription_pointers']) && self::show_user_pointers()) { $dependencies[] = 'wp-pointer'; $pointer_script_params = array('typePointerContent' => sprintf(__('%sChoose Subscription%sThe WooCommerce Subscriptions extension adds two new subscription product types - %sSimple subscription%s and %sVariable subscription%s.%s', 'woocommerce-subscriptions'), '<h3>', '</h3><p>', '<em>', '</em>', '<em>', '</em>', '</p>'), 'pricePointerContent' => sprintf(__('%sSet a Price%sSubscription prices are a little different to other product prices. For a subscription, you can set a billing period, length, sign-up fee and free trial.%s', 'woocommerce-subscriptions'), '<h3>', '</h3><p>', '</p>')); wp_enqueue_script('woocommerce_subscriptions_admin_pointers', plugin_dir_url(WC_Subscriptions::$plugin_file) . 'js/admin-pointers.js', $dependencies, WC_Subscriptions::$version); wp_localize_script('woocommerce_subscriptions_admin_pointers', 'WCSPointers', apply_filters('woocommerce_subscriptions_admin_pointer_script_parameters', $pointer_script_params)); wp_enqueue_style('wp-pointer'); } } // Maybe add the admin notice if ($is_activation_screen) { $woocommerce_plugin_dir_file = self::get_woocommerce_plugin_dir_file(); if (!empty($woocommerce_plugin_dir_file)) { wp_enqueue_style('woocommerce-activation', plugins_url('/assets/css/activation.css', self::get_woocommerce_plugin_dir_file()), array(), WC_Subscriptions::$version); if (!isset($_GET['page']) || 'wcs-about' != $_GET['page']) { add_action('admin_notices', __CLASS__ . '::admin_installed_notice'); } } delete_transient(WC_Subscriptions::$activation_transient); } if ($is_woocommerce_screen || $is_activation_screen) { wp_enqueue_style('woocommerce_admin_styles', $woocommerce->plugin_url() . '/assets/css/admin.css', array(), WC_Subscriptions::$version); wp_enqueue_style('woocommerce_subscriptions_admin', plugin_dir_url(WC_Subscriptions::$plugin_file) . 'css/admin.css', array('woocommerce_admin_styles'), WC_Subscriptions::$version); } }
/** * Enqueues stylesheet for the My Subscriptions table on the My Account page. * * @since 1.5 */ public static function enqueue_styles($styles) { if (WC_Subscriptions::is_woocommerce_pre_2_3() && is_page(get_option('woocommerce_myaccount_page_id'))) { $styles['woocommerce-subscriptions'] = array('src' => str_replace(array('http:', 'https:'), '', plugin_dir_url(__FILE__)) . 'css/woocommerce-subscriptions.css', 'deps' => 'woocommerce-smallscreen', 'version' => WC_VERSION, 'media' => ''); } return $styles; }