/** * Bulk edit * @param integer $post_id * @param WC_Product $product */ public function bulk_edit_save($post_id, $product) { $old_regular_price = $product->regular_price; $old_sale_price = $product->sale_price; // Save fields if (!empty($_REQUEST['change_weight']) && isset($_REQUEST['_weight'])) { update_post_meta($post_id, '_weight', wc_clean(stripslashes($_REQUEST['_weight']))); } if (!empty($_REQUEST['change_dimensions'])) { if (isset($_REQUEST['_length'])) { update_post_meta($post_id, '_length', wc_clean(stripslashes($_REQUEST['_length']))); } if (isset($_REQUEST['_width'])) { update_post_meta($post_id, '_width', wc_clean(stripslashes($_REQUEST['_width']))); } if (isset($_REQUEST['_height'])) { update_post_meta($post_id, '_height', wc_clean(stripslashes($_REQUEST['_height']))); } } if (!empty($_REQUEST['_tax_status'])) { update_post_meta($post_id, '_tax_status', wc_clean($_REQUEST['_tax_status'])); } if (!empty($_REQUEST['_tax_class'])) { $tax_class = wc_clean($_REQUEST['_tax_class']); if ('standard' == $tax_class) { $tax_class = ''; } update_post_meta($post_id, '_tax_class', $tax_class); } if (!empty($_REQUEST['_stock_status'])) { $stock_status = wc_clean($_REQUEST['_stock_status']); if ($product->is_type('variable')) { foreach ($product->get_children() as $child_id) { if ('yes' !== get_post_meta($child_id, '_manage_stock', true)) { wc_update_product_stock_status($child_id, $stock_status); } } WC_Product_Variable::sync_stock_status($post_id); } else { wc_update_product_stock_status($post_id, $stock_status); } } if (!empty($_REQUEST['_shipping_class'])) { $shipping_class = '_no_shipping_class' == $_REQUEST['_shipping_class'] ? '' : wc_clean($_REQUEST['_shipping_class']); wp_set_object_terms($post_id, $shipping_class, 'product_shipping_class'); } if (!empty($_REQUEST['_visibility'])) { if (update_post_meta($post_id, '_visibility', wc_clean($_REQUEST['_visibility']))) { do_action('woocommerce_product_set_visibility', $post_id, wc_clean($_REQUEST['_visibility'])); } } if (!empty($_REQUEST['_featured'])) { if (update_post_meta($post_id, '_featured', stripslashes($_REQUEST['_featured']))) { delete_transient('wc_featured_products'); } } // Sold Individually if (!empty($_REQUEST['_sold_individually'])) { if ($_REQUEST['_sold_individually'] == 'yes') { update_post_meta($post_id, '_sold_individually', 'yes'); } else { update_post_meta($post_id, '_sold_individually', ''); } } // Handle price - remove dates and set to lowest if ($product->is_type('simple') || $product->is_type('external')) { $price_changed = false; if (!empty($_REQUEST['change_regular_price'])) { $change_regular_price = absint($_REQUEST['change_regular_price']); $regular_price = esc_attr(stripslashes($_REQUEST['_regular_price'])); switch ($change_regular_price) { case 1: $new_price = $regular_price; break; case 2: if (strstr($regular_price, '%')) { $percent = str_replace('%', '', $regular_price) / 100; $new_price = $old_regular_price + round($old_regular_price * $percent, wc_get_price_decimals()); } else { $new_price = $old_regular_price + $regular_price; } break; case 3: if (strstr($regular_price, '%')) { $percent = str_replace('%', '', $regular_price) / 100; $new_price = max(0, $old_regular_price - round($old_regular_price * $percent, wc_get_price_decimals())); } else { $new_price = max(0, $old_regular_price - $regular_price); } break; default: break; } if (isset($new_price) && $new_price != $old_regular_price) { $price_changed = true; $new_price = round($new_price, wc_get_price_decimals()); update_post_meta($post_id, '_regular_price', $new_price); $product->regular_price = $new_price; } } if (!empty($_REQUEST['change_sale_price'])) { $change_sale_price = absint($_REQUEST['change_sale_price']); $sale_price = esc_attr(stripslashes($_REQUEST['_sale_price'])); switch ($change_sale_price) { case 1: $new_price = $sale_price; break; case 2: if (strstr($sale_price, '%')) { $percent = str_replace('%', '', $sale_price) / 100; $new_price = $old_sale_price + $old_sale_price * $percent; } else { $new_price = $old_sale_price + $sale_price; } break; case 3: if (strstr($sale_price, '%')) { $percent = str_replace('%', '', $sale_price) / 100; $new_price = max(0, $old_sale_price - $old_sale_price * $percent); } else { $new_price = max(0, $old_sale_price - $sale_price); } break; case 4: if (strstr($sale_price, '%')) { $percent = str_replace('%', '', $sale_price) / 100; $new_price = max(0, $product->regular_price - $product->regular_price * $percent); } else { $new_price = max(0, $product->regular_price - $sale_price); } break; default: break; } if (isset($new_price) && $new_price != $old_sale_price) { $price_changed = true; $new_price = !empty($new_price) || '0' === $new_price ? round($new_price, wc_get_price_decimals()) : ''; update_post_meta($post_id, '_sale_price', $new_price); $product->sale_price = $new_price; } } if ($price_changed) { update_post_meta($post_id, '_sale_price_dates_from', ''); update_post_meta($post_id, '_sale_price_dates_to', ''); if ($product->regular_price < $product->sale_price) { $product->sale_price = ''; update_post_meta($post_id, '_sale_price', ''); } if ($product->sale_price) { update_post_meta($post_id, '_price', $product->sale_price); } else { update_post_meta($post_id, '_price', $product->regular_price); } } } // Handle stock if (!$product->is_type('grouped')) { if (!empty($_REQUEST['change_stock'])) { update_post_meta($post_id, '_manage_stock', 'yes'); wc_update_product_stock($post_id, wc_stock_amount($_REQUEST['_stock'])); } if (!empty($_REQUEST['_manage_stock'])) { if ($_REQUEST['_manage_stock'] == 'yes') { update_post_meta($post_id, '_manage_stock', 'yes'); } else { update_post_meta($post_id, '_manage_stock', 'no'); wc_update_product_stock($post_id, 0); } } if (!empty($_REQUEST['_backorders'])) { update_post_meta($post_id, '_backorders', wc_clean($_REQUEST['_backorders'])); } } do_action('woocommerce_product_bulk_edit_save', $product); }
/** * Register the stylesheets for the public-facing side of the site. * * @since 1.0.0 */ public function enqueue_scripts() { global $post, $product; if (is_object($post) && class_exists('WooCommerce')) { $is_product_type_variable = 'false'; if (function_exists('wc_get_product')) { $product = wc_get_product($post); if ($product) { if ($product->is_type('variable') && is_single()) { $is_product_type_variable = 'true'; } } } $attach_id = isset($_SESSION['attach_id']) && !empty($_SESSION['attach_id']) ? $_SESSION['attach_id'] : ''; if (!empty($attach_id)) { $total_word = get_post_meta($attach_id, 'total_word', true); } else { $total_word = ''; } if (!empty($attach_id)) { $total_character = get_post_meta($attach_id, 'total_character', true); } else { $total_character = ''; } wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'js/woocommerce-price-per-word-public.js', array('jquery'), $this->version, false); if (wp_script_is($this->plugin_name)) { wp_localize_script($this->plugin_name, 'woocommerce_price_per_word_params', apply_filters('woocommerce_price_per_word_params', array('ajax_url' => admin_url('admin-ajax.php'), 'woocommerce_price_per_word_params_nonce' => wp_create_nonce("woocommerce_price_per_word_params_nonce"), 'total_word' => $total_word, 'total_character' => $total_character, 'is_product_type_variable' => $is_product_type_variable, 'woocommerce_currency_symbol_js' => get_woocommerce_currency_symbol(), 'woocommerce_price_num_decimals' => wc_get_price_decimals(), 'aewcppw_word_character' => $this->wppw_get_product_type(), 'aewcppw_allow_users_to_enter_qty' => $this->aewcppw_allow_users_to_enter_qty()))); } wp_enqueue_script($this->plugin_name . '-bn', plugin_dir_url(__FILE__) . 'js/woocommerce-price-per-word-bn.js', array('jquery'), $this->version, false); } }
/** * Add a rate * * Add a shipping rate. If taxes are not set they will be calculated based on cost. * * @param array $args (default: array()) */ public function add_rate($args = array()) { $defaults = array('id' => '', 'label' => '', 'cost' => '0', 'taxes' => '', 'calc_tax' => 'per_order'); $args = wp_parse_args($args, $defaults); extract($args); // Id and label are required if (!$id || !$label) { return; } // Handle cost $total_cost = round(is_array($cost) ? array_sum($cost) : $cost, wc_get_price_decimals()); // Taxes - if not an array and not set to false, calc tax based on cost and passed calc_tax variable // This saves shipping methods having to do complex tax calculations if (!is_array($taxes) && $taxes !== false && $total_cost > 0 && $this->is_taxable()) { $taxes = array(); switch ($calc_tax) { case "per_item": // If we have an array of costs we can look up each items tax class and add tax accordingly if (is_array($cost)) { $cart = WC()->cart->get_cart(); foreach ($cost as $cost_key => $amount) { if (!isset($cart[$cost_key])) { continue; } $_product = $cart[$cost_key]['data']; $rates = WC_Tax::get_shipping_tax_rates($_product->get_tax_class()); $item_taxes = WC_Tax::calc_shipping_tax($amount, $rates); // Sum the item taxes foreach (array_keys($taxes + $item_taxes) as $key) { $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0); } } // Add any cost for the order - order costs are in the key 'order' if (isset($cost['order'])) { $rates = WC_Tax::get_shipping_tax_rates(); $item_taxes = WC_Tax::calc_shipping_tax($cost['order'], $rates); // Sum the item taxes foreach (array_keys($taxes + $item_taxes) as $key) { $taxes[$key] = (isset($item_taxes[$key]) ? $item_taxes[$key] : 0) + (isset($taxes[$key]) ? $taxes[$key] : 0); } } } break; default: $rates = WC_Tax::get_shipping_tax_rates(); $taxes = WC_Tax::calc_shipping_tax($total_cost, $rates); break; } } $this->rates[] = new WC_Shipping_Rate($id, $label, $total_cost, $taxes, $this->id); }
/** * Uses the WooCommerce currency display settings to format CSV price values instead of machine-readable values * * @param array $item_data the data "items" columns in the CSV Export file * @return array - updated item data */ function sv_wc_csv_export_localize_price_items_columns($item_data) { $decimals = wc_get_price_decimals(); $decimal_separator = wc_get_price_decimal_separator(); $thousand_separator = wc_get_price_thousand_separator(); $price_data = array('subtotal', 'subtotal_tax', 'total', 'total_tax', 'refunded'); // localize price for each piece of price data foreach ($price_data as $data_key) { if (isset($item_data[$data_key])) { $item_data[$data_key] = number_format($item_data[$data_key], $decimals, $decimal_separator, $thousand_separator); } } return $item_data; }
/** * Constructor for the cart class. Loads options and hooks in the init method. */ public function __construct() { $this->prices_include_tax = wc_prices_include_tax(); $this->round_at_subtotal = get_option('woocommerce_tax_round_at_subtotal') == 'yes'; $this->tax_display_cart = get_option('woocommerce_tax_display_cart'); $this->dp = wc_get_price_decimals(); $this->display_totals_ex_tax = $this->tax_display_cart == 'excl'; $this->display_cart_ex_tax = $this->tax_display_cart == 'excl'; add_action('wp_loaded', array($this, 'init')); // Get cart after WP and plugins are loaded. add_action('wp', array($this, 'maybe_set_cart_cookies'), 99); // Set cookies add_action('shutdown', array($this, 'maybe_set_cart_cookies'), 0); // Set cookies before shutdown and ob flushing add_action('woocommerce_add_to_cart', array($this, 'calculate_totals'), 20, 0); add_action('woocommerce_applied_coupon', array($this, 'calculate_totals'), 20, 0); }
/** * Enqueue scripts */ public function admin_scripts() { global $post; get_currentuserinfo(); $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; // Register scripts wp_register_script('woocommerce_admin', WC()->plugin_url() . '/assets/js/admin/woocommerce_admin' . $suffix . '.js', array('jquery', 'jquery-blockui', 'jquery-ui-sortable', 'jquery-ui-widget', 'jquery-ui-core', 'jquery-tiptip'), WC_VERSION); wp_register_script('jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array('jquery'), '2.66', true); wp_register_script('jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip' . $suffix . '.js', array('jquery'), WC_VERSION, true); wp_register_script('accounting', WC()->plugin_url() . '/assets/js/admin/accounting' . $suffix . '.js', array('jquery'), '0.3.2'); wp_register_script('round', WC()->plugin_url() . '/assets/js/admin/round' . $suffix . '.js', array('jquery'), WC_VERSION); wp_register_script('wc-admin-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes' . $suffix . '.js', array('jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'accounting', 'round', 'wc-enhanced-select', 'plupload-all', 'stupidtable'), WC_VERSION); wp_register_script('qrcode', WC()->plugin_url() . '/assets/js/admin/jquery.qrcode.min.js', array('jquery'), WC_VERSION); wp_register_script('stupidtable', WC()->plugin_url() . '/assets/js/stupidtable/stupidtable' . $suffix . '.js', array('jquery'), WC_VERSION); wp_register_script('wc-admin-notices', WC()->plugin_url() . '/assets/js/admin/woocommerce_notices' . $suffix . '.js', array('jquery'), WC_VERSION, true); // Select2 is the replacement for chosen wp_register_script('select2', WC()->plugin_url() . '/assets/js/select2/select2' . $suffix . '.js', array('jquery'), '3.5.2'); wp_register_script('wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array('jquery', 'select2'), WC_VERSION); wp_localize_script('select2', 'wc_select_params', array('i18n_matches_1' => _x('One result is available, press enter to select it.', 'enhanced select', 'woocommerce'), 'i18n_matches_n' => _x('%qty% results are available, use up and down arrow keys to navigate.', 'enhanced select', 'woocommerce'), 'i18n_no_matches' => _x('No matches found', 'enhanced select', 'woocommerce'), 'i18n_ajax_error' => _x('Loading failed', 'enhanced select', 'woocommerce'), 'i18n_input_too_short_1' => _x('Please enter 1 or more characters', 'enhanced select', 'woocommerce'), 'i18n_input_too_short_n' => _x('Please enter %qty% or more characters', 'enhanced select', 'woocommerce'), 'i18n_input_too_long_1' => _x('Please delete 1 character', 'enhanced select', 'woocommerce'), 'i18n_input_too_long_n' => _x('Please delete %qty% characters', 'enhanced select', 'woocommerce'), 'i18n_selection_too_long_1' => _x('You can only select 1 item', 'enhanced select', 'woocommerce'), 'i18n_selection_too_long_n' => _x('You can only select %qty% items', 'enhanced select', 'woocommerce'), 'i18n_load_more' => _x('Loading more results…', 'enhanced select', 'woocommerce'), 'i18n_searching' => _x('Searching…', 'enhanced select', 'woocommerce'))); wp_localize_script('wc-enhanced-select', 'wc_enhanced_select_params', array('ajax_url' => admin_url('admin-ajax.php'), 'search_products_nonce' => wp_create_nonce('search-products'), 'search_customers_nonce' => wp_create_nonce('search-customers'))); // Accounting wp_localize_script('accounting', 'accounting_params', array('mon_decimal_point' => wc_get_price_decimal_separator())); // WooCommerce admin pages wp_enqueue_script('woocommerce_admin'); wp_enqueue_script('iris'); wp_enqueue_script('wc-enhanced-select'); wp_enqueue_script('jquery-ui-sortable'); wp_enqueue_script('jquery-ui-autocomplete'); $locale = localeconv(); $decimal = isset($locale['decimal_point']) ? $locale['decimal_point'] : '.'; $params = array('i18n_decimal_error' => sprintf(__('Please enter in decimal (%s) format without thousand separators.', 'woocommerce'), $decimal), 'i18n_mon_decimal_error' => sprintf(__('Please enter in monetary decimal (%s) format without thousand separators and currency symbols.', 'woocommerce'), wc_get_price_decimal_separator()), 'i18n_country_iso_error' => __('Please enter in country code with two capital letters.', 'woocommerce'), 'i18_sale_less_than_regular_error' => __('Please enter in a value less than the regular price.', 'woocommerce'), 'decimal_point' => $decimal, 'mon_decimal_point' => wc_get_price_decimal_separator()); wp_localize_script('woocommerce_admin', 'woocommerce_admin', $params); // Meta boxes wp_enqueue_media(); wp_enqueue_script('wc-admin-product-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product' . $suffix . '.js', array('wc-admin-meta-boxes'), WC_VERSION); wp_enqueue_script('wc-admin-variation-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product-variation' . $suffix . '.js', array('wc-admin-meta-boxes'), WC_VERSION); $params = array('post_id' => isset($post->ID) ? $post->ID : '', 'plugin_url' => WC()->plugin_url(), 'ajax_url' => admin_url('admin-ajax.php'), 'woocommerce_placeholder_img_src' => wc_placeholder_img_src(), 'add_variation_nonce' => wp_create_nonce("add-variation"), 'link_variation_nonce' => wp_create_nonce("link-variations"), 'delete_variations_nonce' => wp_create_nonce("delete-variations"), 'i18n_link_all_variations' => esc_js(__('Are you sure you want to link all variations? This will create a new variation for each and every possible combination of variation attributes (max 50 per run).', 'woocommerce')), 'i18n_enter_a_value' => esc_js(__('Enter a value', 'woocommerce')), 'i18n_enter_a_value_fixed_or_percent' => esc_js(__('Enter a value (fixed or %)', 'woocommerce')), 'i18n_delete_all_variations' => esc_js(__('Are you sure you want to delete all variations? This cannot be undone.', 'woocommerce')), 'i18n_last_warning' => esc_js(__('Last warning, are you sure?', 'woocommerce')), 'i18n_choose_image' => esc_js(__('Choose an image', 'woocommerce')), 'i18n_set_image' => esc_js(__('Set variation image', 'woocommerce')), 'i18n_variation_added' => esc_js(__("variation added", 'woocommerce')), 'i18n_variations_added' => esc_js(__("variations added", 'woocommerce')), 'i18n_no_variations_added' => esc_js(__("No variations added", 'woocommerce')), 'i18n_remove_variation' => esc_js(__('Are you sure you want to remove this variation?', 'woocommerce')), 'i18n_scheduled_sale_start' => esc_js(__('Sale start date (YYYY-MM-DD format or leave blank)', 'woocommerce')), 'i18n_scheduled_sale_end' => esc_js(__('Sale end date (YYYY-MM-DD format or leave blank)', 'woocommerce'))); wp_localize_script('wc-admin-variation-meta-boxes', 'woocommerce_admin_meta_boxes_variations', $params); $params = array('remove_item_notice' => __('Are you sure you want to remove the selected items? If you have previously reduced this item\'s stock, or this order was submitted by a customer, you will need to manually restore the item\'s stock.', 'woocommerce'), 'i18n_select_items' => __('Please select some items.', 'woocommerce'), 'i18n_do_refund' => __('Are you sure you wish to process this refund? This action cannot be undone.', 'woocommerce'), 'i18n_delete_refund' => __('Are you sure you wish to delete this refund? This action cannot be undone.', 'woocommerce'), 'i18n_delete_tax' => __('Are you sure you wish to delete this tax column? This action cannot be undone.', 'woocommerce'), 'remove_item_meta' => __('Remove this item meta?', 'woocommerce'), 'remove_attribute' => __('Remove this attribute?', 'woocommerce'), 'name_label' => __('Name', 'woocommerce'), 'remove_label' => __('Remove', 'woocommerce'), 'click_to_toggle' => __('Click to toggle', 'woocommerce'), 'values_label' => __('Value(s)', 'woocommerce'), 'text_attribute_tip' => __('Enter some text, or some attributes by pipe (|) separating values.', 'woocommerce'), 'visible_label' => __('Visible on the product page', 'woocommerce'), 'used_for_variations_label' => __('Used for variations', 'woocommerce'), 'new_attribute_prompt' => __('Enter a name for the new attribute term:', 'woocommerce'), 'calc_totals' => __('Calculate totals based on order items, discounts, and shipping?', 'woocommerce'), 'calc_line_taxes' => __('Calculate line taxes? This will calculate taxes based on the customers country. If no billing/shipping is set it will use the store base country.', 'woocommerce'), 'copy_billing' => __('Copy billing information to shipping information? This will remove any currently entered shipping information.', 'woocommerce'), 'load_billing' => __('Load the customer\'s billing information? This will remove any currently entered billing information.', 'woocommerce'), 'load_shipping' => __('Load the customer\'s shipping information? This will remove any currently entered shipping information.', 'woocommerce'), 'featured_label' => __('Featured', 'woocommerce'), 'prices_include_tax' => esc_attr(get_option('woocommerce_prices_include_tax')), 'round_at_subtotal' => esc_attr(get_option('woocommerce_tax_round_at_subtotal')), 'no_customer_selected' => __('No customer selected', 'woocommerce'), 'plugin_url' => WC()->plugin_url(), 'ajax_url' => admin_url('admin-ajax.php'), 'order_item_nonce' => wp_create_nonce('order-item'), 'add_attribute_nonce' => wp_create_nonce('add-attribute'), 'save_attributes_nonce' => wp_create_nonce('save-attributes'), 'calc_totals_nonce' => wp_create_nonce('calc-totals'), 'get_customer_details_nonce' => wp_create_nonce('get-customer-details'), 'search_products_nonce' => wp_create_nonce('search-products'), 'grant_access_nonce' => wp_create_nonce('grant-access'), 'revoke_access_nonce' => wp_create_nonce('revoke-access'), 'add_order_note_nonce' => wp_create_nonce('add-order-note'), 'delete_order_note_nonce' => wp_create_nonce('delete-order-note'), 'calendar_image' => WC()->plugin_url() . '/assets/images/calendar.png', 'post_id' => isset($post->ID) ? $post->ID : '', 'base_country' => WC()->countries->get_base_country(), 'currency_format_num_decimals' => wc_get_price_decimals(), 'currency_format_symbol' => get_woocommerce_currency_symbol(), 'currency_format_decimal_sep' => esc_attr(wc_get_price_decimal_separator()), 'currency_format_thousand_sep' => esc_attr(wc_get_price_thousand_separator()), 'currency_format' => esc_attr(str_replace(array('%1$s', '%2$s'), array('%s', '%v'), get_woocommerce_price_format())), 'rounding_precision' => WC_ROUNDING_PRECISION, 'tax_rounding_mode' => WC_TAX_ROUNDING_MODE, 'product_types' => array_map('sanitize_title', get_terms('product_type', array('hide_empty' => false, 'fields' => 'names'))), 'default_attribute_visibility' => apply_filters('default_attribute_visibility', false), 'default_attribute_variation' => apply_filters('default_attribute_variation', false), 'i18n_download_permission_fail' => __('Could not grant access - the user may already have permission for this file or billing email is not set. Ensure the billing email is set, and the order has been saved.', 'woocommerce'), 'i18n_permission_revoke' => __('Are you sure you want to revoke access to this download?', 'woocommerce'), 'i18n_tax_rate_already_exists' => __('You cannot add the same tax rate twice!', 'woocommerce'), 'i18n_product_type_alert' => __('Your product has variations! Before changing the product type, it is a good idea to delete the variations to avoid errors in the stock reports.', 'woocommerce')); wp_localize_script('wc-admin-meta-boxes', 'woocommerce_admin_meta_boxes', $params); }
/** * Get an array of all sale and regular prices from all variations. This is used for example when displaying the price range at variable product level or seeing if the variable product is on sale. * * Can be filtered by plugins which modify costs, but otherwise will include the raw meta costs unlike get_price() which runs costs through the woocommerce_get_price filter. * This is to ensure modified prices are not cached, unless intended. * * @param bool $display Are prices for display? If so, taxes will be calculated. * @return array() Array of RAW prices, regular prices, and sale prices with keys set to variation ID. */ public function get_variation_prices($display = false) { global $wp_filter; /** * Transient name for storing prices for this product (note: Max transient length is 45) * @since 2.5.0 a single transient is used per product for all prices, rather than many transients per product. */ $transient_name = 'wc_var_prices_' . $this->id; /** * Create unique cache key based on the tax location (affects displayed/cached prices), product version and active price filters. * DEVELOPERS should filter this hash if offering conditonal pricing to keep it unique. * @var string */ if ($display) { $price_hash = array(get_option('woocommerce_tax_display_shop', 'excl'), WC_Tax::get_rates()); } else { $price_hash = array(false); } $filter_names = array('woocommerce_variation_prices_price', 'woocommerce_variation_prices_regular_price', 'woocommerce_variation_prices_sale_price'); foreach ($filter_names as $filter_name) { if (!empty($wp_filter[$filter_name])) { $price_hash[$filter_name] = array(); foreach ($wp_filter[$filter_name] as $priority => $callbacks) { $price_hash[$filter_name][] = array_values(wp_list_pluck($callbacks, 'function')); } } } $price_hash = md5(json_encode(apply_filters('woocommerce_get_variation_prices_hash', $price_hash, $this, $display))); // If the value has already been generated, we don't need to grab the values again. if (empty($this->prices_array[$price_hash])) { // Get value of transient $prices_array = array_filter((array) json_decode(strval(get_transient($transient_name)), true)); // If the product version has changed, reset cache if (empty($prices_array['version']) || $prices_array['version'] !== WC_Cache_Helper::get_transient_version('product')) { $this->prices_array = array('version' => WC_Cache_Helper::get_transient_version('product')); } // If the prices are not stored for this hash, generate them if (empty($prices_array[$price_hash])) { $prices = array(); $regular_prices = array(); $sale_prices = array(); $variation_ids = $this->get_children(true); foreach ($variation_ids as $variation_id) { if ($variation = $this->get_child($variation_id)) { $price = apply_filters('woocommerce_variation_prices_price', $variation->price, $variation, $this); $regular_price = apply_filters('woocommerce_variation_prices_regular_price', $variation->regular_price, $variation, $this); $sale_price = apply_filters('woocommerce_variation_prices_sale_price', $variation->sale_price, $variation, $this); // Skip empty prices if ('' === $price) { continue; } // If sale price does not equal price, the product is not yet on sale if ($sale_price === $regular_price || $sale_price !== $price) { $sale_price = $regular_price; } // If we are getting prices for display, we need to account for taxes if ($display) { if ('incl' === get_option('woocommerce_tax_display_shop')) { $price = '' === $price ? '' : $variation->get_price_including_tax(1, $price); $regular_price = '' === $regular_price ? '' : $variation->get_price_including_tax(1, $regular_price); $sale_price = '' === $sale_price ? '' : $variation->get_price_including_tax(1, $sale_price); } else { $price = '' === $price ? '' : $variation->get_price_excluding_tax(1, $price); $regular_price = '' === $regular_price ? '' : $variation->get_price_excluding_tax(1, $regular_price); $sale_price = '' === $sale_price ? '' : $variation->get_price_excluding_tax(1, $sale_price); } } $prices[$variation_id] = wc_format_decimal($price, wc_get_price_decimals()); $regular_prices[$variation_id] = wc_format_decimal($regular_price, wc_get_price_decimals()); $sale_prices[$variation_id] = wc_format_decimal($sale_price . '.00', wc_get_price_decimals()); } } asort($prices); asort($regular_prices); asort($sale_prices); $prices_array[$price_hash] = array('price' => $prices, 'regular_price' => $regular_prices, 'sale_price' => $sale_prices); set_transient($transient_name, json_encode($prices_array), DAY_IN_SECONDS * 30); } /** * Give plugins one last chance to filter the variation prices array which has been generated. */ $this->prices_array[$price_hash] = apply_filters('woocommerce_variation_prices', $prices_array[$price_hash], $this, $display); } /** * Return the values. */ return $this->prices_array[$price_hash]; }
/** * Get the site index. * * This endpoint describes the capabilities of the site. * * @since 2.3 * @return array Index entity */ public function get_index() { // General site data $available = array('store' => array('name' => get_option('blogname'), 'description' => get_option('blogdescription'), 'URL' => get_option('siteurl'), 'wc_version' => WC()->version, 'routes' => array(), 'meta' => array('timezone' => wc_timezone_string(), 'currency' => get_woocommerce_currency(), 'currency_format' => get_woocommerce_currency_symbol(), 'currency_position' => get_option('woocommerce_currency_pos'), 'thousand_separator' => get_option('woocommerce_price_decimal_sep'), 'decimal_separator' => get_option('woocommerce_price_thousand_sep'), 'price_num_decimals' => wc_get_price_decimals(), 'tax_included' => wc_prices_include_tax(), 'weight_unit' => get_option('woocommerce_weight_unit'), 'dimension_unit' => get_option('woocommerce_dimension_unit'), 'ssl_enabled' => 'yes' === get_option('woocommerce_force_ssl_checkout'), 'permalinks_enabled' => '' !== get_option('permalink_structure'), 'links' => array('help' => 'http://woothemes.github.io/woocommerce-rest-api-docs/')))); // Find the available routes foreach ($this->get_routes() as $route => $callbacks) { $data = array(); $route = preg_replace('#\\(\\?P(<\\w+?>).*?\\)#', '$1', $route); foreach (self::$method_map as $name => $bitmask) { foreach ($callbacks as $callback) { // Skip to the next route if any callback is hidden if ($callback[1] & self::HIDDEN_ENDPOINT) { continue 3; } if ($callback[1] & $bitmask) { $data['supports'][] = $name; } if ($callback[1] & self::ACCEPT_DATA) { $data['accepts_data'] = true; } // For non-variable routes, generate links if (strpos($route, '<') === false) { $data['meta'] = array('self' => get_woocommerce_api_url($route)); } } } $available['store']['routes'][$route] = apply_filters('woocommerce_api_endpoints_description', $data); } return apply_filters('woocommerce_api_index', $available); }
/** * Get the main chart. * * @return string */ public function get_main_chart() { global $wp_locale; if (empty($this->show_categories)) { ?> <div class="chart-container"> <p class="chart-prompt"><?php _e('← Choose a category to view stats', 'woocommerce'); ?> </p> </div> <?php } else { $chart_data = array(); $index = 0; foreach ($this->show_categories as $category) { $category = get_term($category, 'product_cat'); $product_ids = $this->get_products_in_category($category->term_id); $category_chart_data = array(); for ($i = 0; $i <= $this->chart_interval; $i++) { $interval_total = 0; switch ($this->chart_groupby) { case 'day': $time = strtotime(date('Ymd', strtotime("+{$i} DAY", $this->start_date))) * 1000; break; case 'month': default: $time = strtotime(date('Ym', strtotime("+{$i} MONTH", $this->start_date)) . '01') * 1000; break; } foreach ($product_ids as $id) { if (isset($this->item_sales_and_times[$time][$id])) { $interval_total += $this->item_sales_and_times[$time][$id]; } } $category_chart_data[] = array($time, (double) wc_format_decimal($interval_total, wc_get_price_decimals())); } $chart_data[$category->term_id]['category'] = $category->name; $chart_data[$category->term_id]['data'] = $category_chart_data; $index++; } ?> <div class="chart-container"> <div class="chart-placeholder main"></div> </div> <script type="text/javascript"> var main_chart; jQuery(function(){ var drawGraph = function( highlight ) { var series = [ <?php $index = 0; foreach ($chart_data as $data) { $color = isset($this->chart_colours[$index]) ? $this->chart_colours[$index] : $this->chart_colours[0]; $width = $this->barwidth / sizeof($chart_data); $offset = $width * $index; $series = $data['data']; foreach ($series as $key => $series_data) { $series[$key][0] = $series_data[0] + $offset; } echo '{ label: "' . esc_js($data['category']) . '", data: jQuery.parseJSON( "' . json_encode($series) . '" ), color: "' . $color . '", bars: { fillColor: "' . $color . '", fill: true, show: true, lineWidth: 1, align: "center", barWidth: ' . $width * 0.75 . ', stack: false }, ' . $this->get_currency_tooltip() . ', enable_tooltip: true, prepend_label: true },'; $index++; } ?> ]; if ( highlight !== 'undefined' && series[ highlight ] ) { highlight_series = series[ highlight ]; highlight_series.color = '#9c5d90'; if ( highlight_series.bars ) { highlight_series.bars.fillColor = '#9c5d90'; } if ( highlight_series.lines ) { highlight_series.lines.lineWidth = 5; } } main_chart = jQuery.plot( jQuery('.chart-placeholder.main'), series, { legend: { show: false }, grid: { color: '#aaa', borderColor: 'transparent', borderWidth: 0, hoverable: true }, xaxes: [ { color: '#aaa', reserveSpace: true, position: "bottom", tickColor: 'transparent', mode: "time", timeformat: "<?php if ($this->chart_groupby == 'day') { echo '%d %b'; } else { echo '%b'; } ?> ", monthNames: <?php echo json_encode(array_values($wp_locale->month_abbrev)); ?> , tickLength: 1, minTickSize: [1, "<?php echo $this->chart_groupby; ?> "], tickSize: [1, "<?php echo $this->chart_groupby; ?> "], font: { color: "#aaa" } } ], yaxes: [ { min: 0, tickDecimals: 2, color: 'transparent', font: { color: "#aaa" } } ], } ); jQuery('.chart-placeholder').resize(); } drawGraph(); jQuery('.highlight_series').hover( function() { drawGraph( jQuery(this).data('series') ); }, function() { drawGraph(); } ); }); </script> <?php } }
?> <?php if (wc_tax_enabled()) { ?> <?php foreach ($order->get_tax_totals() as $code => $tax) { ?> <tr> <td class="label"><?php echo $tax->label; ?> :</td> <td class="total"><?php if (($refunded = $order->get_total_tax_refunded_by_rate_id($tax->rate_id)) > 0) { echo '<del>' . strip_tags($tax->formatted_amount) . '</del> <ins>' . wc_price(WC_Tax::round($tax->amount, wc_get_price_decimals()) - WC_Tax::round($refunded, wc_get_price_decimals()), array('currency' => $order->get_order_currency())) . '</ins>'; } else { echo $tax->formatted_amount; } ?> </td> <td width="1%"></td> </tr> <?php } ?> <?php } ?> <?php
/** * Add a shipping rate. If taxes are not set they will be calculated based on cost. * @param array $args (default: array()) */ public function add_rate($args = array()) { $args = wp_parse_args($args, array('id' => '', 'label' => '', 'cost' => '0', 'taxes' => '', 'calc_tax' => 'per_order', 'meta_data' => array())); // ID and label are required if (!$args['id'] || !$args['label']) { return; } // Total up the cost $total_cost = is_array($args['cost']) ? array_sum($args['cost']) : $args['cost']; $taxes = $args['taxes']; // Taxes - if not an array and not set to false, calc tax based on cost and passed calc_tax variable. This saves shipping methods having to do complex tax calculations. if (!is_array($taxes) && $taxes !== false && $total_cost > 0 && $this->is_taxable()) { $taxes = 'per_item' === $args['calc_tax'] ? $this->get_taxes_per_item($args['cost']) : WC_Tax::calc_shipping_tax($total_cost, WC_Tax::get_shipping_tax_rates()); } // Round the total cost after taxes have been calculated. $total_cost = wc_format_decimal($total_cost, wc_get_price_decimals()); // Create rate object $rate = new WC_Shipping_Rate($args['id'], $args['label'], $total_cost, $taxes, $this->id); if (!empty($args['meta_data'])) { foreach ($args['meta_data'] as $key => $value) { $rate->add_meta_data($key, $value); } } $this->rates[$args['id']] = $rate; }
/** * Get rounding precision for internal WC calculations. * Will increase the precision of wc_get_price_decimals by 2 decimals, unless WC_ROUNDING_PRECISION is set to a higher number. * * @since 2.6.3 * @return int */ function wc_get_rounding_precision() { $precision = wc_get_price_decimals() + 2; if (absint(WC_ROUNDING_PRECISION) > $precision) { $precision = absint(WC_ROUNDING_PRECISION); } return $precision; }
/** * Get an array of all sale and regular prices from all variations. This is used for example when displaying the price range at variable product level or seeing if the variable product is on sale. * * Can be filtered by plugins which modify costs, but otherwise will include the raw meta costs unlike get_price() which runs costs through the woocommerce_get_price filter. * This is to ensure modified prices are not cached, unless intended. * * @since 2.7.0 * @param WC_Product * @param bool $include_taxes If taxes should be calculated or not. */ private function read_price_data(&$product, $include_taxes = false) { global $wp_filter; /** * Transient name for storing prices for this product (note: Max transient length is 45) * @since 2.5.0 a single transient is used per product for all prices, rather than many transients per product. */ $transient_name = 'wc_var_prices_' . $product->get_id(); /** * Create unique cache key based on the tax location (affects displayed/cached prices), product version and active price filters. * DEVELOPERS should filter this hash if offering conditonal pricing to keep it unique. * @var string */ $price_hash = $include_taxes ? array(get_option('woocommerce_tax_display_shop', 'excl'), WC_Tax::get_rates()) : array(false); $filter_names = array('woocommerce_variation_prices_price', 'woocommerce_variation_prices_regular_price', 'woocommerce_variation_prices_sale_price'); foreach ($filter_names as $filter_name) { if (!empty($wp_filter[$filter_name])) { $price_hash[$filter_name] = array(); foreach ($wp_filter[$filter_name] as $priority => $callbacks) { $price_hash[$filter_name][] = array_values(wp_list_pluck($callbacks, 'function')); } } } $price_hash[] = WC_Cache_Helper::get_transient_version('product'); $price_hash = md5(json_encode(apply_filters('woocommerce_get_variation_prices_hash', $price_hash, $product, $include_taxes))); /** * $this->prices_array is an array of values which may have been modified from what is stored in transients - this may not match $transient_cached_prices_array. * If the value has already been generated, we don't need to grab the values again so just return them. They are already filtered. */ if (!empty($this->prices_array[$price_hash])) { if ($include_taxes) { $product->set_variation_prices_including_taxes($this->prices_array[$price_hash]); } else { $product->set_variation_prices($this->prices_array[$price_hash]); } /** * No locally cached value? Get the data from the transient or generate it. */ } else { // Get value of transient $transient_cached_prices_array = array_filter((array) json_decode(strval(get_transient($transient_name)), true)); // If the product version has changed since the transient was last saved, reset the transient cache. if (empty($transient_cached_prices_array['version']) || WC_Cache_Helper::get_transient_version('product') !== $transient_cached_prices_array['version']) { $transient_cached_prices_array = array('version' => WC_Cache_Helper::get_transient_version('product')); } // If the prices are not stored for this hash, generate them and add to the transient. if (empty($transient_cached_prices_array[$price_hash])) { $prices = array(); $regular_prices = array(); $sale_prices = array(); $variation_ids = $product->get_visible_children(); foreach ($variation_ids as $variation_id) { if ($variation = wc_get_product($variation_id)) { $price = apply_filters('woocommerce_variation_prices_price', $variation->get_price('edit'), $variation, $product); $regular_price = apply_filters('woocommerce_variation_prices_regular_price', $variation->get_regular_price('edit'), $variation, $product); $sale_price = apply_filters('woocommerce_variation_prices_sale_price', $variation->get_sale_price('edit'), $variation, $product); // Skip empty prices if ('' === $price) { continue; } // If sale price does not equal price, the product is not yet on sale if ($sale_price === $regular_price || $sale_price !== $price) { $sale_price = $regular_price; } // If we are getting prices for display, we need to account for taxes if ($include_taxes) { if ('incl' === get_option('woocommerce_tax_display_shop')) { $price = '' === $price ? '' : wc_get_price_including_tax($variation, array('qty' => 1, 'price' => $price)); $regular_price = '' === $regular_price ? '' : wc_get_price_including_tax($variation, array('qty' => 1, 'price' => $regular_price)); $sale_price = '' === $sale_price ? '' : wc_get_price_including_tax($variation, array('qty' => 1, 'price' => $sale_price)); } else { $price = '' === $price ? '' : wc_get_price_excluding_tax($variation, array('qty' => 1, 'price' => $price)); $regular_price = '' === $regular_price ? '' : wc_get_price_excluding_tax($variation, array('qty' => 1, 'price' => $regular_price)); $sale_price = '' === $sale_price ? '' : wc_get_price_excluding_tax($variation, array('qty' => 1, 'price' => $sale_price)); } } $prices[$variation_id] = wc_format_decimal($price, wc_get_price_decimals()); $regular_prices[$variation_id] = wc_format_decimal($regular_price, wc_get_price_decimals()); $sale_prices[$variation_id] = wc_format_decimal($sale_price . '.00', wc_get_price_decimals()); } } asort($prices); asort($regular_prices); asort($sale_prices); $transient_cached_prices_array[$price_hash] = array('price' => $prices, 'regular_price' => $regular_prices, 'sale_price' => $sale_prices); set_transient($transient_name, json_encode($transient_cached_prices_array), DAY_IN_SECONDS * 30); } /** * Give plugins one last chance to filter the variation prices array which has been generated and store locally to the class. * This value may differ from the transient cache. It is filtered once before storing locally. */ $this->prices_array[$price_hash] = apply_filters('woocommerce_variation_prices', $transient_cached_prices_array[$price_hash], $product, $include_taxes); if ($include_taxes) { $product->set_variation_prices_including_taxes($this->prices_array[$price_hash]); } else { $product->set_variation_prices($this->prices_array[$price_hash]); } } }
/** * Function to include styles & script for 'Generate Coupon' page */ public function generate_coupon_styles_and_scripts() { global $pagenow, $wp_scripts; if (empty($pagenow) || $pagenow != 'admin.php') { return; } if (empty($_GET['page']) || $_GET['page'] != 'woocommerce_smart_coupon_csv_import') { return; } if (!$this->is_wc_gte_21()) { return; } $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; $jquery_version = isset($wp_scripts->registered['jquery-ui-core']->ver) ? $wp_scripts->registered['jquery-ui-core']->ver : '1.9.2'; $locale = localeconv(); $decimal = isset($locale['decimal_point']) ? $locale['decimal_point'] : '.'; wp_enqueue_style('woocommerce_admin_menu_styles', $this->global_wc()->plugin_url() . '/assets/css/menu.css', array(), $this->global_wc()->version); wp_enqueue_style('woocommerce_admin_styles', $this->global_wc()->plugin_url() . '/assets/css/admin.css', array(), $this->global_wc()->version); wp_enqueue_style('jquery-ui-style', '//code.jquery.com/ui/' . $jquery_version . '/themes/smoothness/jquery-ui.css', array(), $jquery_version); $woocommerce_admin_params = array('i18n_decimal_error' => sprintf(__('Please enter in decimal (%s) format without thousand separators.', 'woocommerce'), $decimal), 'i18n_mon_decimal_error' => sprintf(__('Please enter in monetary decimal (%s) format without thousand separators and currency symbols.', 'woocommerce'), wc_get_price_decimal_separator()), 'i18n_country_iso_error' => __('Please enter in country code with two capital letters.', 'woocommerce'), 'i18_sale_less_than_regular_error' => __('Please enter in a value less than the regular price.', 'woocommerce'), 'decimal_point' => $decimal, 'mon_decimal_point' => wc_get_price_decimal_separator()); $woocommerce_admin_meta_boxes_params = array('remove_item_notice' => __('Are you sure you want to remove the selected items? If you have previously reduced this item\'s stock, or this order was submitted by a customer, you will need to manually restore the item\'s stock.', 'woocommerce'), 'i18n_select_items' => __('Please select some items.', 'woocommerce'), 'i18n_do_refund' => __('Are you sure you wish to process this refund? This action cannot be undone.', 'woocommerce'), 'i18n_delete_refund' => __('Are you sure you wish to delete this refund? This action cannot be undone.', 'woocommerce'), 'i18n_delete_tax' => __('Are you sure you wish to delete this tax column? This action cannot be undone.', 'woocommerce'), 'remove_item_meta' => __('Remove this item meta?', 'woocommerce'), 'remove_attribute' => __('Remove this attribute?', 'woocommerce'), 'name_label' => __('Name', 'woocommerce'), 'remove_label' => __('Remove', 'woocommerce'), 'click_to_toggle' => __('Click to toggle', 'woocommerce'), 'values_label' => __('Value(s)', 'woocommerce'), 'text_attribute_tip' => __('Enter some text, or some attributes by pipe (|) separating values.', 'woocommerce'), 'visible_label' => __('Visible on the product page', 'woocommerce'), 'used_for_variations_label' => __('Used for variations', 'woocommerce'), 'new_attribute_prompt' => __('Enter a name for the new attribute term:', 'woocommerce'), 'calc_totals' => __('Calculate totals based on order items, discounts, and shipping?', 'woocommerce'), 'calc_line_taxes' => __('Calculate line taxes? This will calculate taxes based on the customers country. If no billing/shipping is set it will use the store base country.', 'woocommerce'), 'copy_billing' => __('Copy billing information to shipping information? This will remove any currently entered shipping information.', 'woocommerce'), 'load_billing' => __('Load the customer\'s billing information? This will remove any currently entered billing information.', 'woocommerce'), 'load_shipping' => __('Load the customer\'s shipping information? This will remove any currently entered shipping information.', 'woocommerce'), 'featured_label' => __('Featured', 'woocommerce'), 'prices_include_tax' => esc_attr(get_option('woocommerce_prices_include_tax')), 'round_at_subtotal' => esc_attr(get_option('woocommerce_tax_round_at_subtotal')), 'no_customer_selected' => __('No customer selected', 'woocommerce'), 'plugin_url' => $this->global_wc()->plugin_url(), 'ajax_url' => admin_url('admin-ajax.php'), 'order_item_nonce' => wp_create_nonce('order-item'), 'add_attribute_nonce' => wp_create_nonce('add-attribute'), 'save_attributes_nonce' => wp_create_nonce('save-attributes'), 'calc_totals_nonce' => wp_create_nonce('calc-totals'), 'get_customer_details_nonce' => wp_create_nonce('get-customer-details'), 'search_products_nonce' => wp_create_nonce('search-products'), 'grant_access_nonce' => wp_create_nonce('grant-access'), 'revoke_access_nonce' => wp_create_nonce('revoke-access'), 'add_order_note_nonce' => wp_create_nonce('add-order-note'), 'delete_order_note_nonce' => wp_create_nonce('delete-order-note'), 'calendar_image' => $this->global_wc()->plugin_url() . '/assets/images/calendar.png', 'post_id' => '', 'base_country' => $this->global_wc()->countries->get_base_country(), 'currency_format_num_decimals' => wc_get_price_decimals(), 'currency_format_symbol' => get_woocommerce_currency_symbol(), 'currency_format_decimal_sep' => esc_attr(wc_get_price_decimal_separator()), 'currency_format_thousand_sep' => esc_attr(wc_get_price_thousand_separator()), 'currency_format' => esc_attr(str_replace(array('%1$s', '%2$s'), array('%s', '%v'), get_woocommerce_price_format())), 'rounding_precision' => WC_ROUNDING_PRECISION, 'tax_rounding_mode' => WC_TAX_ROUNDING_MODE, 'product_types' => array_map('sanitize_title', get_terms('product_type', array('hide_empty' => false, 'fields' => 'names'))), 'i18n_download_permission_fail' => __('Could not grant access - the user may already have permission for this file or billing email is not set. Ensure the billing email is set, and the order has been saved.', 'woocommerce'), 'i18n_permission_revoke' => __('Are you sure you want to revoke access to this download?', 'woocommerce'), 'i18n_tax_rate_already_exists' => __('You cannot add the same tax rate twice!', 'woocommerce'), 'i18n_product_type_alert' => __('Your product has variations! Before changing the product type, it is a good idea to delete the variations to avoid errors in the stock reports.', 'woocommerce')); if ($this->is_wc_gte_23()) { if (!wp_script_is('wc-admin-coupon-meta-boxes')) { wp_enqueue_script('wc-admin-coupon-meta-boxes', $this->global_wc()->plugin_url() . '/assets/js/admin/meta-boxes-coupon' . $suffix . '.js', array('woocommerce_admin', 'wc-enhanced-select', 'wc-admin-meta-boxes'), $this->global_wc()->version); wp_localize_script('wc-admin-meta-boxes', 'woocommerce_admin_meta_boxes', $woocommerce_admin_meta_boxes_params); wp_enqueue_script('woocommerce_admin', $this->global_wc()->plugin_url() . '/assets/js/admin/woocommerce_admin' . $suffix . '.js', array('jquery', 'jquery-blockui', 'jquery-ui-sortable', 'jquery-ui-widget', 'jquery-ui-core', 'jquery-tiptip'), $this->global_wc()->version); wp_localize_script('woocommerce_admin', 'woocommerce_admin', $woocommerce_admin_params); } } else { if (!wp_script_is('ajax-chosen', 'registered')) { wp_register_script('chosen', $this->global_wc()->plugin_url() . '/assets/js/chosen/chosen.jquery' . $suffix . '.js', array('jquery'), $this->global_wc()->version); wp_register_script('ajax-chosen', $this->global_wc()->plugin_url() . '/assets/js/chosen/ajax-chosen.jquery' . $suffix . '.js', array('jquery', 'woocommerce_admin', 'woocommerce_admin_meta_boxes', 'chosen'), $this->global_wc()->version); } wp_localize_script('woocommerce_admin', 'woocommerce_admin', $woocommerce_admin_params); wp_localize_script('woocommerce_admin_meta_boxes', 'woocommerce_admin_meta_boxes', $woocommerce_admin_meta_boxes_params); wp_enqueue_script('ajax-chosen'); wp_enqueue_style('woocommerce_chosen_styles', $assets_path . 'css/chosen.css'); } }
/** * Test wc_get_price_decimals(). * * @since 2.4 */ public function test_wc_get_price_decimals() { $decimals = get_option('woocommerce_price_num_decimals'); // defualt value $this->assertEquals(2, wc_get_price_decimals()); update_option('woocommerce_price_num_decimals', '1'); $this->assertEquals(1, wc_get_price_decimals()); update_option('woocommerce_price_num_decimals', '-2'); $this->assertEquals(2, wc_get_price_decimals()); update_option('woocommerce_price_num_decimals', '2.50'); $this->assertEquals(2, wc_get_price_decimals()); update_option('woocommerce_price_num_decimals', $decimals); }
/** * Get some setting values for the site that are useful for debugging * purposes. For full settings access, use the settings api. * * @return array */ public function get_settings() { // Get a list of terms used for product/order taxonomies $term_response = array(); $terms = get_terms('product_type', array('hide_empty' => 0)); foreach ($terms as $term) { $term_response[$term->slug] = strtolower($term->name); } // Return array of useful settings for debugging. return array('api_enabled' => 'yes' === get_option('woocommerce_api_enabled'), 'force_ssl' => 'yes' === get_option('woocommerce_force_ssl_checkout'), 'currency' => get_woocommerce_currency(), 'currency_symbol' => get_woocommerce_currency_symbol(), 'currency_position' => get_option('woocommerce_currency_pos'), 'thousand_separator' => wc_get_price_thousand_separator(), 'decimal_separator' => wc_get_price_decimal_separator(), 'number_of_decimals' => wc_get_price_decimals(), 'geolocation_enabled' => in_array(get_option('woocommerce_default_customer_address'), array('geolocation_ajax', 'geolocation')), 'taxonomies' => $term_response); }
/** * Returns the price (including tax). Uses customer tax rates. Can work for a specific $qty for more accurate taxes. * * @param string $price to calculate, left blank to just use get_price() * @return string */ public function get_price_including_tax($qty = 1, $price = '') { if ($price === '') { $price = $this->get_price(); } if ($this->is_taxable()) { if (get_option('woocommerce_prices_include_tax') === 'no') { $tax_rates = WC_Tax::get_rates($this->get_tax_class()); $taxes = WC_Tax::calc_tax($price * $qty, $tax_rates, false); $tax_amount = WC_Tax::get_tax_total($taxes); $price = round($price * $qty + $tax_amount, wc_get_price_decimals()); } else { $tax_rates = WC_Tax::get_rates($this->get_tax_class()); $base_tax_rates = WC_Tax::get_base_tax_rates($this->tax_class); if (!empty(WC()->customer) && WC()->customer->is_vat_exempt()) { $base_taxes = WC_Tax::calc_tax($price * $qty, $base_tax_rates, true); $base_tax_amount = array_sum($base_taxes); $price = round($price * $qty - $base_tax_amount, wc_get_price_decimals()); /** * The woocommerce_adjust_non_base_location_prices filter can stop base taxes being taken off when dealing with out of base locations. * e.g. If a product costs 10 including tax, all users will pay 10 regardless of location and taxes. * This feature is experimental @since 2.4.7 and may change in the future. Use at your risk. */ } elseif ($tax_rates !== $base_tax_rates && apply_filters('woocommerce_adjust_non_base_location_prices', true)) { $base_taxes = WC_Tax::calc_tax($price * $qty, $base_tax_rates, true); $modded_taxes = WC_Tax::calc_tax($price * $qty - array_sum($base_taxes), $tax_rates, false); $price = round($price * $qty - array_sum($base_taxes) + array_sum($modded_taxes), wc_get_price_decimals()); } else { $price = $price * $qty; } } } else { $price = $price * $qty; } return apply_filters('woocommerce_get_price_including_tax', $price, $qty, $this); }
/** * Get the order data for the given ID. * * @since 2.5.0 * @param WC_Order $order The order instance * @return array */ protected function get_order_data($order) { $order_post = get_post($order->id); $dp = wc_get_price_decimals(); $order_data = array('id' => $order->id, 'order_number' => $order->get_order_number(), 'created_at' => $this->format_datetime($order_post->post_date_gmt), 'updated_at' => $this->format_datetime($order_post->post_modified_gmt), 'completed_at' => $this->format_datetime($order->completed_date, true), 'status' => $order->get_status(), 'currency' => $order->get_order_currency(), 'total' => wc_format_decimal($order->get_total(), $dp), 'subtotal' => wc_format_decimal($order->get_subtotal(), $dp), 'total_line_items_quantity' => $order->get_item_count(), 'total_tax' => wc_format_decimal($order->get_total_tax(), $dp), 'total_shipping' => wc_format_decimal($order->get_total_shipping(), $dp), 'cart_tax' => wc_format_decimal($order->get_cart_tax(), $dp), 'shipping_tax' => wc_format_decimal($order->get_shipping_tax(), $dp), 'total_discount' => wc_format_decimal($order->get_total_discount(), $dp), 'shipping_methods' => $order->get_shipping_method(), 'payment_details' => array('method_id' => $order->payment_method, 'method_title' => $order->payment_method_title, 'paid' => isset($order->paid_date)), 'billing_address' => array('first_name' => $order->billing_first_name, 'last_name' => $order->billing_last_name, 'company' => $order->billing_company, 'address_1' => $order->billing_address_1, 'address_2' => $order->billing_address_2, 'city' => $order->billing_city, 'state' => $order->billing_state, 'postcode' => $order->billing_postcode, 'country' => $order->billing_country, 'email' => $order->billing_email, 'phone' => $order->billing_phone), 'shipping_address' => array('first_name' => $order->shipping_first_name, 'last_name' => $order->shipping_last_name, 'company' => $order->shipping_company, 'address_1' => $order->shipping_address_1, 'address_2' => $order->shipping_address_2, 'city' => $order->shipping_city, 'state' => $order->shipping_state, 'postcode' => $order->shipping_postcode, 'country' => $order->shipping_country), 'note' => $order->customer_note, 'customer_ip' => $order->customer_ip_address, 'customer_user_agent' => $order->customer_user_agent, 'customer_id' => $order->get_user_id(), 'view_order_url' => $order->get_view_order_url(), 'line_items' => array(), 'shipping_lines' => array(), 'tax_lines' => array(), 'fee_lines' => array(), 'coupon_lines' => array()); // add line items foreach ($order->get_items() as $item_id => $item) { $product = $order->get_product_from_item($item); $product_id = null; $product_sku = null; // Check if the product exists. if (is_object($product)) { $product_id = isset($product->variation_id) ? $product->variation_id : $product->id; $product_sku = $product->get_sku(); } $meta = new WC_Order_Item_Meta($item, $product); $item_meta = array(); foreach ($meta->get_formatted(null) as $meta_key => $formatted_meta) { $item_meta[] = array('key' => $meta_key, 'label' => $formatted_meta['label'], 'value' => $formatted_meta['value']); } $order_data['line_items'][] = array('id' => $item_id, 'subtotal' => wc_format_decimal($order->get_line_subtotal($item, false, false), $dp), 'subtotal_tax' => wc_format_decimal($item['line_subtotal_tax'], $dp), 'total' => wc_format_decimal($order->get_line_total($item, false, false), $dp), 'total_tax' => wc_format_decimal($item['line_tax'], $dp), 'price' => wc_format_decimal($order->get_item_total($item, false, false), $dp), 'quantity' => wc_stock_amount($item['qty']), 'tax_class' => !empty($item['tax_class']) ? $item['tax_class'] : null, 'name' => $item['name'], 'product_id' => $product_id, 'sku' => $product_sku, 'meta' => $item_meta); } // Add shipping. foreach ($order->get_shipping_methods() as $shipping_item_id => $shipping_item) { $order_data['shipping_lines'][] = array('id' => $shipping_item_id, 'method_id' => $shipping_item['method_id'], 'method_title' => $shipping_item['name'], 'total' => wc_format_decimal($shipping_item['cost'], $dp)); } // Add taxes. foreach ($order->get_tax_totals() as $tax_code => $tax) { $order_data['tax_lines'][] = array('id' => $tax->id, 'rate_id' => $tax->rate_id, 'code' => $tax_code, 'title' => $tax->label, 'total' => wc_format_decimal($tax->amount, $dp), 'compound' => (bool) $tax->is_compound); } // Add fees. foreach ($order->get_fees() as $fee_item_id => $fee_item) { $order_data['fee_lines'][] = array('id' => $fee_item_id, 'title' => $fee_item['name'], 'tax_class' => !empty($fee_item['tax_class']) ? $fee_item['tax_class'] : null, 'total' => wc_format_decimal($order->get_line_total($fee_item), $dp), 'total_tax' => wc_format_decimal($order->get_line_tax($fee_item), $dp)); } // Add coupons. foreach ($order->get_items('coupon') as $coupon_item_id => $coupon_item) { $order_data['coupon_lines'][] = array('id' => $coupon_item_id, 'code' => $coupon_item['name'], 'amount' => wc_format_decimal($coupon_item['discount_amount'], $dp)); } $order_data = apply_filters('woocommerce_cli_order_data', $order_data); return $this->flatten_array($order_data); }
/** * Get an individual variation's data * * @since 2.5.0 * @param WC_Product $product * @return array */ private function get_variation_data($product) { $prices_precision = wc_get_price_decimals(); $variations = array(); foreach ($product->get_children() as $child_id) { $variation = $product->get_child($child_id); if (!$variation->exists()) { continue; } $variations[] = array('id' => $variation->get_variation_id(), 'created_at' => $this->format_datetime($variation->get_post_data()->post_date_gmt), 'updated_at' => $this->format_datetime($variation->get_post_data()->post_modified_gmt), 'downloadable' => $variation->is_downloadable(), 'virtual' => $variation->is_virtual(), 'permalink' => $variation->get_permalink(), 'sku' => $variation->get_sku(), 'price' => wc_format_decimal($variation->get_price(), $prices_precision), 'regular_price' => wc_format_decimal($variation->get_regular_price(), $prices_precision), 'sale_price' => $variation->get_sale_price() ? wc_format_decimal($variation->get_sale_price(), $prices_precision) : null, 'taxable' => $variation->is_taxable(), 'tax_status' => $variation->get_tax_status(), 'tax_class' => $variation->get_tax_class(), 'managing_stock' => $variation->managing_stock(), 'stock_quantity' => $variation->get_stock_quantity(), 'in_stock' => $variation->is_in_stock(), 'backordered' => $variation->is_on_backorder(), 'purchaseable' => $variation->is_purchasable(), 'visible' => $variation->variation_is_visible(), 'on_sale' => $variation->is_on_sale(), 'weight' => $variation->get_weight() ? wc_format_decimal($variation->get_weight(), 2) : null, 'dimensions' => array('length' => $variation->length, 'width' => $variation->width, 'height' => $variation->height, 'unit' => get_option('woocommerce_dimension_unit')), 'shipping_class' => $variation->get_shipping_class(), 'shipping_class_id' => 0 !== $variation->get_shipping_class_id() ? $variation->get_shipping_class_id() : null, 'image' => $this->get_images($variation), 'attributes' => $this->get_attributes($variation), 'downloads' => $this->get_downloads($variation), 'download_limit' => (int) $product->download_limit, 'download_expiry' => (int) $product->download_expiry); } return $variations; }
<td><?php echo wc_get_price_decimal_separator(); ?> </td> </tr> <tr> <td data-export-label="Number of Decimals"><?php _e('Number of Decimals', 'woocommerce'); ?> </td> <td class="help"><?php echo wc_help_tip(__('The number of decimal points shown in displayed prices.', 'woocommerce')); ?> </td> <td><?php echo wc_get_price_decimals(); ?> </td> </tr> </tbody> </table> <table class="wc_status_table widefat" cellspacing="0"> <thead> <tr> <th colspan="3" data-export-label="API"><h2><?php _e('API', 'woocommerce'); ?> </h2></th> </tr> </thead> <tbody>
/** * Calculate totals by looking at the contents of the order. Stores the totals and returns the orders final total. * * @since 2.2 * @param $and_taxes bool Calc taxes if true * @return float calculated grand total */ public function calculate_totals($and_taxes = true) { $cart_subtotal = 0; $cart_total = 0; $fee_total = 0; $cart_subtotal_tax = 0; $cart_total_tax = 0; if ($and_taxes && wc_tax_enabled()) { $this->calculate_taxes(); } // line items foreach ($this->get_items() as $item) { $cart_subtotal += wc_format_decimal(isset($item['line_subtotal']) ? $item['line_subtotal'] : 0); $cart_total += wc_format_decimal(isset($item['line_total']) ? $item['line_total'] : 0); $cart_subtotal_tax += wc_format_decimal(isset($item['line_subtotal_tax']) ? $item['line_subtotal_tax'] : 0); $cart_total_tax += wc_format_decimal(isset($item['line_tax']) ? $item['line_tax'] : 0); } $this->calculate_shipping(); foreach ($this->get_fees() as $item) { $fee_total += $item['line_total']; } $this->set_total($cart_subtotal - $cart_total, 'cart_discount'); $this->set_total($cart_subtotal_tax - $cart_total_tax, 'cart_discount_tax'); $grand_total = round($cart_total + $fee_total + $this->get_total_shipping() + $this->get_cart_tax() + $this->get_shipping_tax(), wc_get_price_decimals()); $this->set_total($grand_total, 'total'); return $grand_total; }
/** * Auto-load in-accessible properties on demand. * * @param mixed $key * @return mixed */ public function __get($key) { switch ($key) { case 'prices_include_tax': return wc_prices_include_tax(); break; case 'round_at_subtotal': return 'yes' === get_option('woocommerce_tax_round_at_subtotal'); break; case 'tax_display_cart': return get_option('woocommerce_tax_display_cart'); break; case 'dp': return wc_get_price_decimals(); break; case 'display_totals_ex_tax': case 'display_cart_ex_tax': return $this->tax_display_cart === 'excl'; break; case 'cart_contents_weight': return $this->get_cart_contents_weight(); break; case 'cart_contents_count': return $this->get_cart_contents_count(); break; case 'tax': _deprecated_argument('WC_Cart->tax', '2.3', 'Use WC_Tax:: directly'); $this->tax = new WC_Tax(); return $this->tax; case 'discount_total': _deprecated_argument('WC_Cart->discount_total', '2.3', 'After tax coupons are no longer supported. For more information see: https://woocommerce.wordpress.com/2014/12/upcoming-coupon-changes-in-woocommerce-2-3/'); return 0; } }
/** * Calculate line total - useful for gateways. * * @param mixed $item * @param bool $inc_tax (default: false) * @param bool $round (default: true) * @return float */ public function get_line_total($item, $inc_tax = false, $round = true) { // Check if we need to add line tax to the line total $line_total = $inc_tax ? $item['line_total'] + $item['line_tax'] : $item['line_total']; // Check if we need to round $line_total = $round ? round($line_total, wc_get_price_decimals()) : $line_total; return apply_filters('woocommerce_order_amount_line_total', $line_total, $this, $item, $inc_tax, $round); }
/** * Enqueue scripts */ public function admin_scripts() { global $wp_query, $post, $current_user; get_currentuserinfo(); $screen = get_current_screen(); $wc_screen_id = sanitize_title(__('WooCommerce', 'woocommerce')); $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; // Register scripts wp_register_script('woocommerce_admin', WC()->plugin_url() . '/assets/js/admin/woocommerce_admin' . $suffix . '.js', array('jquery', 'jquery-blockui', 'jquery-ui-sortable', 'jquery-ui-widget', 'jquery-ui-core', 'jquery-tiptip'), WC_VERSION); wp_register_script('jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array('jquery'), '2.70', true); wp_register_script('jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip' . $suffix . '.js', array('jquery'), WC_VERSION, true); wp_register_script('accounting', WC()->plugin_url() . '/assets/js/admin/accounting' . $suffix . '.js', array('jquery'), '0.4.2'); wp_register_script('round', WC()->plugin_url() . '/assets/js/admin/round' . $suffix . '.js', array('jquery'), WC_VERSION); wp_register_script('wc-admin-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes' . $suffix . '.js', array('jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'accounting', 'round', 'wc-enhanced-select', 'plupload-all', 'stupidtable'), WC_VERSION); wp_register_script('zeroclipboard', WC()->plugin_url() . '/assets/js/zeroclipboard/jquery.zeroclipboard' . $suffix . '.js', array('jquery'), WC_VERSION); wp_register_script('qrcode', WC()->plugin_url() . '/assets/js/jquery-qrcode/jquery.qrcode' . $suffix . '.js', array('jquery'), WC_VERSION); wp_register_script('stupidtable', WC()->plugin_url() . '/assets/js/stupidtable/stupidtable' . $suffix . '.js', array('jquery'), WC_VERSION); // Chosen is @deprecated (2.3) in favour of select2, but is registered for backwards compat wp_register_script('ajax-chosen', WC()->plugin_url() . '/assets/js/chosen/ajax-chosen.jquery' . $suffix . '.js', array('jquery', 'chosen'), WC_VERSION); wp_register_script('chosen', WC()->plugin_url() . '/assets/js/chosen/chosen.jquery' . $suffix . '.js', array('jquery'), WC_VERSION); // Select2 is the replacement for chosen wp_register_script('select2', WC()->plugin_url() . '/assets/js/select2/select2' . $suffix . '.js', array('jquery'), '3.5.2'); wp_register_script('wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array('jquery', 'select2'), WC_VERSION); wp_localize_script('wc-enhanced-select', 'wc_enhanced_select_params', array('i18n_matches_1' => _x('One result is available, press enter to select it.', 'enhanced select', 'woocommerce'), 'i18n_matches_n' => _x('%qty% results are available, use up and down arrow keys to navigate.', 'enhanced select', 'woocommerce'), 'i18n_no_matches' => _x('No matches found', 'enhanced select', 'woocommerce'), 'i18n_ajax_error' => _x('Loading failed', 'enhanced select', 'woocommerce'), 'i18n_input_too_short_1' => _x('Please enter 1 or more characters', 'enhanced select', 'woocommerce'), 'i18n_input_too_short_n' => _x('Please enter %qty% or more characters', 'enhanced select', 'woocommerce'), 'i18n_input_too_long_1' => _x('Please delete 1 character', 'enhanced select', 'woocommerce'), 'i18n_input_too_long_n' => _x('Please delete %qty% characters', 'enhanced select', 'woocommerce'), 'i18n_selection_too_long_1' => _x('You can only select 1 item', 'enhanced select', 'woocommerce'), 'i18n_selection_too_long_n' => _x('You can only select %qty% items', 'enhanced select', 'woocommerce'), 'i18n_load_more' => _x('Loading more results…', 'enhanced select', 'woocommerce'), 'i18n_searching' => _x('Searching…', 'enhanced select', 'woocommerce'), 'ajax_url' => admin_url('admin-ajax.php'), 'search_products_nonce' => wp_create_nonce('search-products'), 'search_customers_nonce' => wp_create_nonce('search-customers'))); // Accounting wp_localize_script('accounting', 'accounting_params', array('mon_decimal_point' => wc_get_price_decimal_separator())); // WooCommerce admin pages if (in_array($screen->id, wc_get_screen_ids())) { wp_enqueue_script('woocommerce_admin'); wp_enqueue_script('iris'); wp_enqueue_script('wc-enhanced-select'); wp_enqueue_script('jquery-ui-sortable'); wp_enqueue_script('jquery-ui-autocomplete'); $locale = localeconv(); $decimal = isset($locale['decimal_point']) ? $locale['decimal_point'] : '.'; $params = array('i18n_decimal_error' => sprintf(__('Please enter in decimal (%s) format without thousand separators.', 'woocommerce'), $decimal), 'i18n_mon_decimal_error' => sprintf(__('Please enter in monetary decimal (%s) format without thousand separators and currency symbols.', 'woocommerce'), wc_get_price_decimal_separator()), 'i18n_country_iso_error' => __('Please enter in country code with two capital letters.', 'woocommerce'), 'i18_sale_less_than_regular_error' => __('Please enter in a value less than the regular price.', 'woocommerce'), 'decimal_point' => $decimal, 'mon_decimal_point' => wc_get_price_decimal_separator()); wp_localize_script('woocommerce_admin', 'woocommerce_admin', $params); } // Edit product category pages if (in_array($screen->id, array('edit-product_cat'))) { wp_enqueue_media(); } // Products if (in_array($screen->id, array('edit-product'))) { wp_enqueue_script('woocommerce_quick-edit', WC()->plugin_url() . '/assets/js/admin/quick-edit' . $suffix . '.js', array('jquery'), WC_VERSION); } // Meta boxes if (in_array($screen->id, array('product', 'edit-product'))) { wp_enqueue_media(); wp_enqueue_script('wc-admin-product-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product' . $suffix . '.js', array('wc-admin-meta-boxes'), WC_VERSION); wp_enqueue_script('wc-admin-variation-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product-variation' . $suffix . '.js', array('wc-admin-meta-boxes'), WC_VERSION); $params = array('post_id' => isset($post->ID) ? $post->ID : '', 'plugin_url' => WC()->plugin_url(), 'ajax_url' => admin_url('admin-ajax.php'), 'woocommerce_placeholder_img_src' => wc_placeholder_img_src(), 'add_variation_nonce' => wp_create_nonce('add-variation'), 'link_variation_nonce' => wp_create_nonce('link-variations'), 'delete_variations_nonce' => wp_create_nonce('delete-variations'), 'load_variations_nonce' => wp_create_nonce('load-variations'), 'save_variations_nonce' => wp_create_nonce('save-variations'), 'bulk_edit_variations_nonce' => wp_create_nonce('bulk-edit-variations'), 'i18n_link_all_variations' => esc_js(__('Are you sure you want to link all variations? This will create a new variation for each and every possible combination of variation attributes (max 50 per run).', 'woocommerce')), 'i18n_enter_a_value' => esc_js(__('Enter a value', 'woocommerce')), 'i18n_enter_a_value_fixed_or_percent' => esc_js(__('Enter a value (fixed or %)', 'woocommerce')), 'i18n_delete_all_variations' => esc_js(__('Are you sure you want to delete all variations? This cannot be undone.', 'woocommerce')), 'i18n_last_warning' => esc_js(__('Last warning, are you sure?', 'woocommerce')), 'i18n_choose_image' => esc_js(__('Choose an image', 'woocommerce')), 'i18n_set_image' => esc_js(__('Set variation image', 'woocommerce')), 'i18n_variation_added' => esc_js(__("variation added", 'woocommerce')), 'i18n_variations_added' => esc_js(__("variations added", 'woocommerce')), 'i18n_no_variations_added' => esc_js(__("No variations added", 'woocommerce')), 'i18n_remove_variation' => esc_js(__('Are you sure you want to remove this variation?', 'woocommerce')), 'i18n_scheduled_sale_start' => esc_js(__('Sale start date (YYYY-MM-DD format or leave blank)', 'woocommerce')), 'i18n_scheduled_sale_end' => esc_js(__('Sale end date (YYYY-MM-DD format or leave blank)', 'woocommerce')), 'i18n_edited_variations' => esc_js(__('Save changes before changing page?', 'woocommerce')), 'i18n_variation_count_single' => esc_js(__('%qty% variation', 'woocommerce')), 'i18n_variation_count_plural' => esc_js(__('%qty% variations', 'woocommerce')), 'variations_per_page' => absint(apply_filters('woocommerce_admin_meta_boxes_variations_per_page', 10))); wp_localize_script('wc-admin-variation-meta-boxes', 'woocommerce_admin_meta_boxes_variations', $params); } if (in_array(str_replace('edit-', '', $screen->id), wc_get_order_types('order-meta-boxes'))) { wp_enqueue_script('wc-admin-order-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-order' . $suffix . '.js', array('wc-admin-meta-boxes'), WC_VERSION); wp_enqueue_script('wc-admin-order-meta-boxes-modal', WC()->plugin_url() . '/assets/js/admin/order-backbone-modal' . $suffix . '.js', array('underscore', 'backbone', 'wc-admin-order-meta-boxes'), WC_VERSION); $params = array('countries' => json_encode(array_merge(WC()->countries->get_allowed_country_states(), WC()->countries->get_shipping_country_states())), 'i18n_select_state_text' => esc_attr__('Select an option…', 'woocommerce')); wp_localize_script('wc-admin-order-meta-boxes', 'woocommerce_admin_meta_boxes_order', $params); } if (in_array($screen->id, array('shop_coupon', 'edit-shop_coupon'))) { wp_enqueue_script('wc-admin-coupon-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-coupon' . $suffix . '.js', array('wc-admin-meta-boxes'), WC_VERSION); } if (in_array(str_replace('edit-', '', $screen->id), array_merge(array('shop_coupon', 'product'), wc_get_order_types('order-meta-boxes')))) { $params = array('remove_item_notice' => __('Are you sure you want to remove the selected items? If you have previously reduced this item\'s stock, or this order was submitted by a customer, you will need to manually restore the item\'s stock.', 'woocommerce'), 'i18n_select_items' => __('Please select some items.', 'woocommerce'), 'i18n_do_refund' => __('Are you sure you wish to process this refund? This action cannot be undone.', 'woocommerce'), 'i18n_delete_refund' => __('Are you sure you wish to delete this refund? This action cannot be undone.', 'woocommerce'), 'i18n_delete_tax' => __('Are you sure you wish to delete this tax column? This action cannot be undone.', 'woocommerce'), 'remove_item_meta' => __('Remove this item meta?', 'woocommerce'), 'remove_attribute' => __('Remove this attribute?', 'woocommerce'), 'name_label' => __('Name', 'woocommerce'), 'remove_label' => __('Remove', 'woocommerce'), 'click_to_toggle' => __('Click to toggle', 'woocommerce'), 'values_label' => __('Value(s)', 'woocommerce'), 'text_attribute_tip' => __('Enter some text, or some attributes by pipe (|) separating values.', 'woocommerce'), 'visible_label' => __('Visible on the product page', 'woocommerce'), 'used_for_variations_label' => __('Used for variations', 'woocommerce'), 'new_attribute_prompt' => __('Enter a name for the new attribute term:', 'woocommerce'), 'calc_totals' => __('Calculate totals based on order items, discounts, and shipping?', 'woocommerce'), 'calc_line_taxes' => __('Calculate line taxes? This will calculate taxes based on the customers country. If no billing/shipping is set it will use the store base country.', 'woocommerce'), 'copy_billing' => __('Copy billing information to shipping information? This will remove any currently entered shipping information.', 'woocommerce'), 'load_billing' => __('Load the customer\'s billing information? This will remove any currently entered billing information.', 'woocommerce'), 'load_shipping' => __('Load the customer\'s shipping information? This will remove any currently entered shipping information.', 'woocommerce'), 'featured_label' => __('Featured', 'woocommerce'), 'prices_include_tax' => esc_attr(get_option('woocommerce_prices_include_tax')), 'round_at_subtotal' => esc_attr(get_option('woocommerce_tax_round_at_subtotal')), 'no_customer_selected' => __('No customer selected', 'woocommerce'), 'plugin_url' => WC()->plugin_url(), 'ajax_url' => admin_url('admin-ajax.php'), 'order_item_nonce' => wp_create_nonce('order-item'), 'add_attribute_nonce' => wp_create_nonce('add-attribute'), 'save_attributes_nonce' => wp_create_nonce('save-attributes'), 'calc_totals_nonce' => wp_create_nonce('calc-totals'), 'get_customer_details_nonce' => wp_create_nonce('get-customer-details'), 'search_products_nonce' => wp_create_nonce('search-products'), 'grant_access_nonce' => wp_create_nonce('grant-access'), 'revoke_access_nonce' => wp_create_nonce('revoke-access'), 'add_order_note_nonce' => wp_create_nonce('add-order-note'), 'delete_order_note_nonce' => wp_create_nonce('delete-order-note'), 'calendar_image' => WC()->plugin_url() . '/assets/images/calendar.png', 'post_id' => isset($post->ID) ? $post->ID : '', 'base_country' => WC()->countries->get_base_country(), 'currency_format_num_decimals' => wc_get_price_decimals(), 'currency_format_symbol' => get_woocommerce_currency_symbol(), 'currency_format_decimal_sep' => esc_attr(wc_get_price_decimal_separator()), 'currency_format_thousand_sep' => esc_attr(wc_get_price_thousand_separator()), 'currency_format' => esc_attr(str_replace(array('%1$s', '%2$s'), array('%s', '%v'), get_woocommerce_price_format())), 'rounding_precision' => WC_ROUNDING_PRECISION, 'tax_rounding_mode' => WC_TAX_ROUNDING_MODE, 'product_types' => array_map('sanitize_title', get_terms('product_type', array('hide_empty' => false, 'fields' => 'names'))), 'i18n_download_permission_fail' => __('Could not grant access - the user may already have permission for this file or billing email is not set. Ensure the billing email is set, and the order has been saved.', 'woocommerce'), 'i18n_permission_revoke' => __('Are you sure you want to revoke access to this download?', 'woocommerce'), 'i18n_tax_rate_already_exists' => __('You cannot add the same tax rate twice!', 'woocommerce'), 'i18n_product_type_alert' => __('Your product has variations! Before changing the product type, it is a good idea to delete the variations to avoid errors in the stock reports.', 'woocommerce')); wp_localize_script('wc-admin-meta-boxes', 'woocommerce_admin_meta_boxes', $params); } // Term ordering - only when sorting by term_order if ((strstr($screen->id, 'edit-pa_') || !empty($_GET['taxonomy']) && in_array($_GET['taxonomy'], apply_filters('woocommerce_sortable_taxonomies', array('product_cat')))) && !isset($_GET['orderby'])) { wp_register_script('woocommerce_term_ordering', WC()->plugin_url() . '/assets/js/admin/term-ordering' . $suffix . '.js', array('jquery-ui-sortable'), WC_VERSION); wp_enqueue_script('woocommerce_term_ordering'); $taxonomy = isset($_GET['taxonomy']) ? wc_clean($_GET['taxonomy']) : ''; $woocommerce_term_order_params = array('taxonomy' => $taxonomy); wp_localize_script('woocommerce_term_ordering', 'woocommerce_term_ordering_params', $woocommerce_term_order_params); } // Product sorting - only when sorting by menu order on the products page if (current_user_can('edit_others_pages') && $screen->id == 'edit-product' && isset($wp_query->query['orderby']) && $wp_query->query['orderby'] == 'menu_order title') { wp_enqueue_script('woocommerce_product_ordering', WC()->plugin_url() . '/assets/js/admin/product-ordering' . $suffix . '.js', array('jquery-ui-sortable'), WC_VERSION, true); } // Reports Pages if (in_array($screen->id, apply_filters('woocommerce_reports_screen_ids', array($wc_screen_id . '_page_wc-reports', 'toplevel_page_wc-reports', 'dashboard')))) { wp_enqueue_script('wc-reports', WC()->plugin_url() . '/assets/js/admin/reports' . $suffix . '.js', array('jquery', 'jquery-ui-datepicker'), WC_VERSION); wp_enqueue_script('flot', WC()->plugin_url() . '/assets/js/admin/jquery.flot' . $suffix . '.js', array('jquery'), WC_VERSION); wp_enqueue_script('flot-resize', WC()->plugin_url() . '/assets/js/admin/jquery.flot.resize' . $suffix . '.js', array('jquery', 'flot'), WC_VERSION); wp_enqueue_script('flot-time', WC()->plugin_url() . '/assets/js/admin/jquery.flot.time' . $suffix . '.js', array('jquery', 'flot'), WC_VERSION); wp_enqueue_script('flot-pie', WC()->plugin_url() . '/assets/js/admin/jquery.flot.pie' . $suffix . '.js', array('jquery', 'flot'), WC_VERSION); wp_enqueue_script('flot-stack', WC()->plugin_url() . '/assets/js/admin/jquery.flot.stack' . $suffix . '.js', array('jquery', 'flot'), WC_VERSION); } // API settings if ($wc_screen_id . '_page_wc-settings' === $screen->id && isset($_GET['section']) && 'keys' == $_GET['section']) { wp_enqueue_script('wc-api-keys', WC()->plugin_url() . '/assets/js/admin/api-keys' . $suffix . '.js', array('jquery', 'woocommerce_admin', 'underscore', 'backbone', 'qrcode', 'zeroclipboard'), WC_VERSION, true); wp_localize_script('wc-api-keys', 'woocommerce_admin_api_keys', array('ajax_url' => admin_url('admin-ajax.php'), 'update_api_nonce' => wp_create_nonce('update-api-key'))); } // System status if ($wc_screen_id . '_page_wc-status' === $screen->id) { wp_enqueue_script('zeroclipboard'); } if (in_array($screen->id, array('user-edit', 'profile'))) { wp_enqueue_script('wc-users', WC()->plugin_url() . '/assets/js/admin/users' . $suffix . '.js', array('jquery', 'wc-enhanced-select'), WC_VERSION, true); wp_localize_script('wc-users', 'wc_users_params', array('countries' => json_encode(array_merge(WC()->countries->get_allowed_country_states(), WC()->countries->get_shipping_country_states())), 'i18n_select_state_text' => esc_attr__('Select an option…', 'woocommerce'))); } }
/** * Add a shipping rate. If taxes are not set they will be calculated based on cost. * @param array $args (default: array()) */ public function add_rate($args = array()) { $args = wp_parse_args($args, array('id' => $this->get_rate_id(), 'label' => '', 'cost' => '0', 'taxes' => '', 'calc_tax' => 'per_order', 'meta_data' => array(), 'package' => false)); // ID and label are required if (!$args['id'] || !$args['label']) { return; } // Total up the cost $total_cost = is_array($args['cost']) ? array_sum($args['cost']) : $args['cost']; $taxes = $args['taxes']; // Taxes - if not an array and not set to false, calc tax based on cost and passed calc_tax variable. This saves shipping methods having to do complex tax calculations. if (!is_array($taxes) && $taxes !== false && $total_cost > 0 && $this->is_taxable()) { $taxes = 'per_item' === $args['calc_tax'] ? $this->get_taxes_per_item($args['cost']) : WC_Tax::calc_shipping_tax($total_cost, WC_Tax::get_shipping_tax_rates()); } // Round the total cost after taxes have been calculated. $total_cost = wc_format_decimal($total_cost, wc_get_price_decimals()); // Create rate object $rate = new WC_Shipping_Rate($args['id'], $args['label'], $total_cost, $taxes, $this->id); if (!empty($args['meta_data'])) { foreach ($args['meta_data'] as $key => $value) { $rate->add_meta_data($key, $value); } } // Store package data if ($args['package']) { $items_in_package = array(); foreach ($args['package']['contents'] as $item) { $product = $item['data']; $items_in_package[] = $product->get_title() . ' × ' . $item['quantity']; } $rate->add_meta_data(__('Items', 'woocommerce'), implode(', ', $items_in_package)); } $this->rates[$args['id']] = $rate; }
/** * Round our totals correctly * @param string $amount * @return string */ private function round_chart_totals($amount) { if (is_array($amount)) { return array_map(array($this, 'round_chart_totals'), $amount); } else { return wc_format_decimal($amount, wc_get_price_decimals()); } }
/** * Calculate line total - useful for gateways. * * @param object $item * @param bool $inc_tax (default: false). * @param bool $round (default: true). * @return float */ public function get_line_total($item, $inc_tax = false, $round = true) { $total = 0; if (is_callable(array($item, 'get_total'))) { // Check if we need to add line tax to the line total. $total = $inc_tax ? $item->get_total() + $item->get_total_tax() : $item->get_total(); // Check if we need to round. $total = $round ? round($total, wc_get_price_decimals()) : $total; } return apply_filters('woocommerce_order_amount_line_total', $total, $this, $item, $inc_tax, $round); }
/** * Format the price with a currency symbol. * * @param float $price * @param array $args (default: array()) * @return string */ function wc_price($price, $args = array()) { extract(apply_filters('wc_price_args', wp_parse_args($args, array('ex_tax_label' => false, 'currency' => '', 'decimal_separator' => wc_get_price_decimal_separator(), 'thousand_separator' => wc_get_price_thousand_separator(), 'decimals' => wc_get_price_decimals(), 'price_format' => get_woocommerce_price_format())))); $negative = $price < 0; $price = apply_filters('raw_woocommerce_price', floatval($negative ? $price * -1 : $price)); $price = apply_filters('formatted_woocommerce_price', number_format($price, $decimals, $decimal_separator, $thousand_separator), $price, $decimals, $decimal_separator, $thousand_separator); if (apply_filters('woocommerce_price_trim_zeros', false) && $decimals > 0) { $price = wc_trim_zeros($price); } $formatted_price = ($negative ? '-' : '') . sprintf($price_format, '<span class="woocommerce-Price-currencySymbol">' . get_woocommerce_currency_symbol($currency) . '</span>', $price); $return = '<span class="woocommerce-Price-amount amount">' . $formatted_price . '</span>'; if ($ex_tax_label && wc_tax_enabled()) { $return .= ' <small class="woocommerce-Price-taxLabel tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>'; } return apply_filters('wc_price', $return, $price, $args); }
/** * Returns the price (including tax). Uses customer tax rates. Can work for a specific $qty for more accurate taxes. * * @param string $price to calculate, left blank to just use get_price() * @return string */ public function get_price_including_tax($qty = 1, $price = '') { if ($price === '') { $price = $this->get_price(); } if ($this->is_taxable()) { if (get_option('woocommerce_prices_include_tax') === 'no') { $tax_rates = WC_Tax::get_rates($this->get_tax_class()); $taxes = WC_Tax::calc_tax($price * $qty, $tax_rates, false); $tax_amount = WC_Tax::get_tax_total($taxes); $price = round($price * $qty + $tax_amount, wc_get_price_decimals()); } else { $tax_rates = WC_Tax::get_rates($this->get_tax_class()); $base_tax_rates = WC_Tax::get_base_tax_rates($this->tax_class); if (!empty(WC()->customer) && WC()->customer->is_vat_exempt()) { $base_taxes = WC_Tax::calc_tax($price * $qty, $base_tax_rates, true); $base_tax_amount = array_sum($base_taxes); $price = round($price * $qty - $base_tax_amount, wc_get_price_decimals()); } elseif ($tax_rates !== $base_tax_rates) { $base_taxes = WC_Tax::calc_tax($price * $qty, $base_tax_rates, true); $modded_taxes = WC_Tax::calc_tax($price * $qty - array_sum($base_taxes), $tax_rates, false); $price = round($price * $qty - array_sum($base_taxes) + array_sum($modded_taxes), wc_get_price_decimals()); } else { $price = $price * $qty; } } } else { $price = $price * $qty; } return apply_filters('woocommerce_get_price_including_tax', $price, $qty, $this); }
/** * Formal total costs - format to the number of decimal places for the base currency. * * @access public * @param mixed $number * @deprecated 2.1 * @return string */ function woocommerce_format_total($number) { _deprecated_function(__FUNCTION__, '2.1', 'wc_format_decimal()'); return wc_format_decimal($number, wc_get_price_decimals(), false); }