/** * Create an order. Error codes: * 520 - Cannot insert order into the database. * 521 - Cannot get order after creation. * 522 - Cannot update order. * 525 - Cannot create line item. * 526 - Cannot create fee item. * 527 - Cannot create shipping item. * 528 - Cannot create tax item. * 529 - Cannot create coupon item. * * @throws Exception * @param $data Posted data. * @return int|WP_ERROR */ public function create_order($data) { // Give plugins the opportunity to create an order themselves. if ($order_id = apply_filters('woocommerce_create_order', null, $this)) { return $order_id; } try { $order_id = absint(WC()->session->get('order_awaiting_payment')); $cart_hash = md5(json_encode(wc_clean(WC()->cart->get_cart_for_session())) . WC()->cart->total); /** * If there is an order pending payment, we can resume it here so * long as it has not changed. If the order has changed, i.e. * different items or cost, create a new order. We use a hash to * detect changes which is based on cart items + order total. */ if ($order_id && ($order = wc_get_order($order_id)) && $order->has_cart_hash($cart_hash) && $order->has_status(array('pending', 'failed'))) { // Action for 3rd parties. do_action('woocommerce_resume_order', $order_id); // Remove all items - we will re-add them later. $order->remove_order_items(); } else { $order = new WC_Order(); } foreach ($data as $key => $value) { if (is_callable(array($order, "set_{$key}"))) { $order->{"set_{$key}"}($value); } } $order->set_created_via('checkout'); $order->set_cart_hash($cart_hash); $order->set_customer_id(apply_filters('woocommerce_checkout_customer_id', get_current_user_id())); $order->set_currency(get_woocommerce_currency()); $order->set_prices_include_tax('yes' === get_option('woocommerce_prices_include_tax')); $order->set_customer_ip_address(WC_Geolocation::get_ip_address()); $order->set_customer_user_agent(wc_get_user_agent()); $order->set_customer_note(isset($data['order_comments']) ? $data['order_comments'] : ''); $order->set_payment_method($data['payment_method']); $order->set_shipping_total(WC()->cart->shipping_total); $order->set_discount_total(WC()->cart->get_cart_discount_total()); $order->set_discount_tax(WC()->cart->get_cart_discount_tax_total()); $order->set_cart_tax(WC()->cart->tax_total); $order->set_shipping_tax(WC()->cart->shipping_tax_total); $order->set_total(WC()->cart->total); $this->create_order_line_items($order); $this->create_order_fee_lines($order); $this->create_order_shipping_lines($order); $this->create_order_tax_lines($order); $this->create_order_coupon_lines($order); $order_id = $order->save(); // Let plugins add their own meta data. do_action('woocommerce_checkout_update_order_meta', $order_id, $data); return $order_id; } catch (Exception $e) { return new WP_Error('checkout-error', $e->getMessage()); } }
/** * Register/queue frontend scripts. */ public static function load_scripts() { global $post; if (!did_action('before_woocommerce_init')) { return; } $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; $lightbox_en = 'yes' === get_option('woocommerce_enable_lightbox'); $ajax_cart_en = 'yes' === get_option('woocommerce_enable_ajax_add_to_cart'); $assets_path = str_replace(array('http:', 'https:'), '', WC()->plugin_url()) . '/assets/'; $frontend_script_path = $assets_path . 'js/frontend/'; // Register any scripts for later use, or used as dependencies self::register_script('select2', $assets_path . 'js/select2/select2' . $suffix . '.js', array('jquery'), '3.5.4'); self::register_script('jquery-blockui', $assets_path . 'js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array('jquery'), '2.70'); self::register_script('jquery-payment', $assets_path . 'js/jquery-payment/jquery.payment' . $suffix . '.js', array('jquery'), '1.4.1'); self::register_script('jquery-cookie', $assets_path . 'js/jquery-cookie/jquery.cookie' . $suffix . '.js', array('jquery'), '1.4.1'); self::register_script('wc-credit-card-form', $frontend_script_path . 'credit-card-form' . $suffix . '.js', array('jquery', 'jquery-payment')); self::register_script('wc-add-to-cart-variation', $frontend_script_path . 'add-to-cart-variation' . $suffix . '.js', array('jquery', 'wp-util')); self::register_script('wc-single-product', $frontend_script_path . 'single-product' . $suffix . '.js', array('jquery')); self::register_script('wc-country-select', $frontend_script_path . 'country-select' . $suffix . '.js', array('jquery')); self::register_script('wc-address-i18n', $frontend_script_path . 'address-i18n' . $suffix . '.js', array('jquery')); self::register_script('wc-password-strength-meter', $frontend_script_path . 'password-strength-meter' . $suffix . '.js', array('jquery', 'password-strength-meter')); // Register frontend scripts conditionally if ($ajax_cart_en) { self::enqueue_script('wc-add-to-cart', $frontend_script_path . 'add-to-cart' . $suffix . '.js'); } if (is_cart()) { self::enqueue_script('wc-cart', $frontend_script_path . 'cart' . $suffix . '.js', array('jquery', 'wc-country-select', 'wc-address-i18n')); } if (is_checkout() || is_account_page()) { self::enqueue_script('select2'); self::enqueue_style('select2', $assets_path . 'css/select2.css'); // Password strength meter. // Load in checkout, account login and edit account page. if ('no' === get_option('woocommerce_registration_generate_password') && !is_user_logged_in() || is_edit_account_page()) { self::enqueue_script('wc-password-strength-meter'); } } if (is_checkout()) { self::enqueue_script('wc-checkout', $frontend_script_path . 'checkout' . $suffix . '.js', array('jquery', 'woocommerce', 'wc-country-select', 'wc-address-i18n')); } if (is_add_payment_method_page()) { self::enqueue_script('wc-add-payment-method', $frontend_script_path . 'add-payment-method' . $suffix . '.js', array('jquery', 'woocommerce')); } if (is_lost_password_page()) { self::enqueue_script('wc-lost-password', $frontend_script_path . 'lost-password' . $suffix . '.js', array('jquery', 'woocommerce')); } if ($lightbox_en && (is_product() || !empty($post->post_content) && strstr($post->post_content, '[product_page'))) { self::enqueue_script('prettyPhoto', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto' . $suffix . '.js', array('jquery'), '3.1.6', true); self::enqueue_script('prettyPhoto-init', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto.init' . $suffix . '.js', array('jquery', 'prettyPhoto')); self::enqueue_style('woocommerce_prettyPhoto_css', $assets_path . 'css/prettyPhoto.css'); } if (is_product()) { self::enqueue_script('wc-single-product'); } if ('geolocation_ajax' === get_option('woocommerce_default_customer_address')) { // Exclude common bots from geolocation by user agent. $ua = wc_get_user_agent(); if (!strstr($ua, 'bot') && !strstr($ua, 'spider') && !strstr($ua, 'crawl')) { self::enqueue_script('wc-geolocation', $frontend_script_path . 'geolocation' . $suffix . '.js', array('jquery')); } } // Global frontend scripts self::enqueue_script('woocommerce', $frontend_script_path . 'woocommerce' . $suffix . '.js', array('jquery', 'jquery-blockui')); self::enqueue_script('wc-cart-fragments', $frontend_script_path . 'cart-fragments' . $suffix . '.js', array('jquery', 'jquery-cookie')); // CSS Styles if ($enqueue_styles = self::get_styles()) { foreach ($enqueue_styles as $handle => $args) { self::enqueue_style($handle, $args['src'], $args['deps'], $args['version'], $args['media']); } } }
/** * Get the customer's default location. * * Filtered, and set to base location or left blank. If cache-busting, * this should only be used when 'location' is set in the querystring. * * @todo should the woocommerce_default_country option be renamed to contain 'base'? * @todo deprecate woocommerce_customer_default_location and support an array filter only to cover all cases. * @since 2.3.0 * @return array */ function wc_get_customer_default_location() { $location = array(); switch (get_option('woocommerce_default_customer_address')) { case 'geolocation_ajax': case 'geolocation': // Exclude common bots from geolocation by user agent. $ua = wc_get_user_agent(); if (!strstr($ua, 'bot') && !strstr($ua, 'spider') && !strstr($ua, 'crawl')) { $location = WC_Geolocation::geolocate_ip('', true, false); } // Base fallback. if (empty($location['country'])) { $location = wc_format_country_state_string(apply_filters('woocommerce_customer_default_location', get_option('woocommerce_default_country'))); } break; case 'base': $location = wc_format_country_state_string(apply_filters('woocommerce_customer_default_location', get_option('woocommerce_default_country'))); break; default: $location = wc_format_country_state_string(apply_filters('woocommerce_customer_default_location', '')); break; } return apply_filters('woocommerce_customer_default_location_array', $location); }
/** * Store user agents. Used for tracker. * @since 2.7.0 */ function wc_maybe_store_user_agent($user_login, $user) { if ('yes' === get_option('woocommerce_allow_tracking', 'no') && user_can($user, 'manage_woocommerce')) { $admin_user_agents = array_filter((array) get_option('woocommerce_tracker_ua', array())); $admin_user_agents[] = wc_get_user_agent(); update_option('woocommerce_tracker_ua', array_unique($admin_user_agents)); } }
/** * Create an order. Error codes: * 520 - Cannot insert order into the database. * 521 - Cannot get order after creation. * 522 - Cannot update order. * 525 - Cannot create line item. * 526 - Cannot create fee item. * 527 - Cannot create shipping item. * 528 - Cannot create tax item. * 529 - Cannot create coupon item. * @throws Exception * @return int|WP_ERROR */ public function create_order() { global $wpdb; // Give plugins the opportunity to create an order themselves if ($order_id = apply_filters('woocommerce_create_order', null, $this)) { return $order_id; } try { // Start transaction if available wc_transaction_query('start'); // Insert or update the post data $order_id = absint(WC()->session->order_awaiting_payment); $cart_hash = md5(json_encode(wc_clean(WC()->cart->get_cart_for_session())) . WC()->cart->total); /** * If there is an order pending payment, we can resume it here so * long as it has not changed. If the order has changed, i.e. * different items or cost, create a new order. We use a hash to * detect changes which is based on cart items + order total. */ if ($order_id && ($order = wc_get_order($order_id)) && $order->has_cart_hash($cart_hash) && $order->has_status(array('pending', 'failed'))) { // Action for 3rd parties. do_action('woocommerce_resume_order', $order_id); // Remove all items - we will re-add them later. $order->remove_order_items(); /** * Not resuming - lets create a new order object. */ } else { $order = new WC_Order(); } $order->set_created_via('checkout'); $order->set_cart_hash($cart_hash); $order->set_customer_id($this->customer_id); $order->set_currency(get_woocommerce_currency()); $order->set_prices_include_tax('yes' === get_option('woocommerce_prices_include_tax')); $order->set_customer_ip_address(WC_Geolocation::get_ip_address()); $order->set_customer_user_agent(wc_get_user_agent()); $order->set_customer_note(isset($this->posted['order_comments']) ? $this->posted['order_comments'] : ''); $order->set_payment_method($this->payment_method); $order->set_shipping_total(WC()->cart->shipping_total); $order->set_discount_total(WC()->cart->get_cart_discount_total()); $order->set_discount_tax(WC()->cart->get_cart_discount_tax_total()); $order->set_cart_tax(WC()->cart->tax_total); $order->set_shipping_tax(WC()->cart->shipping_tax_total); $order->set_total(WC()->cart->total); // Billing and shipping addresses if ($address_keys = array_merge(array_keys($this->checkout_fields['billing']), array_keys($this->checkout_fields['shipping']))) { foreach ($address_keys as $key) { if (is_callable(array($order, "set_{$key}"))) { $order->{"set_{$key}"}($this->get_posted_address_data(str_replace(array('billing_', 'shipping_'), '', $key), strstr($key, 'billing_') ? 'billing' : 'shipping')); } } } // Add line items. foreach (WC()->cart->get_cart() as $cart_item_key => $values) { $product = $values['data']; $item = new WC_Order_Item_Product(array('quantity' => $values['quantity'], 'name' => $product ? $product->get_title() : '', 'tax_class' => $product ? $product->get_tax_class() : '', 'product_id' => $product && isset($product->id) ? $product->id : 0, 'variation_id' => $product && isset($product->variation_id) ? $product->variation_id : 0, 'variation' => $values['variation'], 'subtotal' => $values['line_subtotal'], 'total' => $values['line_total'], 'subtotal_tax' => $values['line_subtotal_tax'], 'total_tax' => $values['line_tax'], 'taxes' => $values['line_tax_data'])); $item->set_backorder_meta(); // Set this to pass to legacy actions @todo remove in future release $item->legacy_values = $values; $item->legacy_cart_item_key = $cart_item_key; $order->add_item($item); } // Add fees foreach (WC()->cart->get_fees() as $fee_key => $fee) { $item = new WC_Order_Item_Fee(array('name' => $fee->name, 'tax_class' => $fee->taxable ? $fee->tax_class : 0, 'total' => $fee->amount, 'total_tax' => $fee->tax, 'taxes' => array('total' => $fee->tax_data))); // Set this to pass to legacy actions @todo remove in future release $item->legacy_fee = $fee; $item->legacy_fee_key = $fee_key; $order->add_item($item); } // Store shipping for all packages foreach (WC()->shipping->get_packages() as $package_key => $package) { if (isset($package['rates'][$this->shipping_methods[$package_key]])) { $shipping_rate = $package['rates'][$this->shipping_methods[$package_key]]; $item = new WC_Order_Item_Shipping(array('method_title' => $shipping_rate->label, 'method_id' => $shipping_rate->id, 'total' => wc_format_decimal($shipping_rate->cost), 'taxes' => $shipping_rate->taxes, 'meta_data' => $shipping_rate->get_meta_data())); // Set this to pass to legacy actions @todo remove in future release $item->legacy_package_key = $package_key; $order->add_item($item); } } // Store tax rows foreach (array_keys(WC()->cart->taxes + WC()->cart->shipping_taxes) as $tax_rate_id) { if ($tax_rate_id && apply_filters('woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated') !== $tax_rate_id) { $order->add_item(new WC_Order_Item_Tax(array('rate_id' => $tax_rate_id, 'tax_total' => WC()->cart->get_tax_amount($tax_rate_id), 'shipping_tax_total' => WC()->cart->get_shipping_tax_amount($tax_rate_id), 'rate_code' => WC_Tax::get_rate_code($tax_rate_id), 'label' => WC_Tax::get_rate_label($tax_rate_id), 'compound' => WC_Tax::is_compound($tax_rate_id)))); } } // Store coupons foreach (WC()->cart->get_coupons() as $code => $coupon) { $item = new WC_Order_Item_Coupon(array('code' => $code, 'discount' => WC()->cart->get_coupon_discount_amount($code), 'discount_tax' => WC()->cart->get_coupon_discount_tax_amount($code))); $order->add_item($item); } // Save the order $order_id = $order->save(); // Update user meta $this->update_customer_data(); // Let plugins add their own meta data do_action('woocommerce_checkout_update_order_meta', $order_id, $this->posted); // If we got here, the order was created without problems! wc_transaction_query('commit'); } catch (Exception $e) { // There was an error adding order data! wc_transaction_query('rollback'); return new WP_Error('checkout-error', $e->getMessage()); } return $order_id; }
/** * Register/queue frontend scripts. */ public static function load_scripts() { global $post; if (!did_action('before_woocommerce_init')) { return; } $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; $ajax_cart_en = 'yes' === get_option('woocommerce_enable_ajax_add_to_cart'); $assets_path = str_replace(array('http:', 'https:'), '', WC()->plugin_url()) . '/assets/'; $frontend_script_path = $assets_path . 'js/frontend/'; // Register any scripts for later use, or used as dependencies self::register_script('select2', $assets_path . 'js/select2/select2' . $suffix . '.js', array('jquery'), '3.5.4'); self::register_script('jquery-blockui', $assets_path . 'js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array('jquery'), '2.70'); self::register_script('jquery-payment', $assets_path . 'js/jquery-payment/jquery.payment' . $suffix . '.js', array('jquery'), '1.4.1'); self::register_script('js-cookie', $assets_path . 'js/js-cookie/js.cookie' . $suffix . '.js', array(), '2.1.3'); self::register_script('wc-credit-card-form', $frontend_script_path . 'credit-card-form' . $suffix . '.js', array('jquery', 'jquery-payment')); self::register_script('wc-add-to-cart-variation', $frontend_script_path . 'add-to-cart-variation' . $suffix . '.js', array('jquery', 'wp-util')); self::register_script('wc-single-product', $frontend_script_path . 'single-product' . $suffix . '.js', array('jquery')); self::register_script('wc-country-select', $frontend_script_path . 'country-select' . $suffix . '.js', array('jquery')); self::register_script('wc-address-i18n', $frontend_script_path . 'address-i18n' . $suffix . '.js', array('jquery')); self::register_script('wc-password-strength-meter', $frontend_script_path . 'password-strength-meter' . $suffix . '.js', array('jquery', 'password-strength-meter')); // Register frontend scripts conditionally if ($ajax_cart_en) { self::enqueue_script('wc-add-to-cart', $frontend_script_path . 'add-to-cart' . $suffix . '.js'); } if (is_cart()) { self::enqueue_script('wc-cart', $frontend_script_path . 'cart' . $suffix . '.js', array('jquery', 'wc-country-select', 'wc-address-i18n')); } if (is_checkout() || is_account_page()) { self::enqueue_script('select2'); self::enqueue_style('select2', $assets_path . 'css/select2.css'); // Password strength meter. // Load in checkout, account login and edit account page. if ('no' === get_option('woocommerce_registration_generate_password') && !is_user_logged_in() || is_edit_account_page() || is_lost_password_page()) { self::enqueue_script('wc-password-strength-meter'); } } if (is_checkout()) { self::enqueue_script('wc-checkout', $frontend_script_path . 'checkout' . $suffix . '.js', array('jquery', 'woocommerce', 'wc-country-select', 'wc-address-i18n')); } if (is_add_payment_method_page()) { self::enqueue_script('wc-add-payment-method', $frontend_script_path . 'add-payment-method' . $suffix . '.js', array('jquery', 'woocommerce')); } if (is_lost_password_page()) { self::enqueue_script('wc-lost-password', $frontend_script_path . 'lost-password' . $suffix . '.js', array('jquery', 'woocommerce')); } if (is_product() || !empty($post->post_content) && strstr($post->post_content, '[product_page')) { self::enqueue_script('flexslider', $assets_path . 'js/flexslider/jquery.flexslider' . $suffix . '.js', array('jquery'), '2.7.0', true); self::enqueue_script('photoswipe', $assets_path . 'js/photoswipe/photoswipe' . $suffix . '.js', '4.1.1', true); self::enqueue_script('photoswipe-ui-default', $assets_path . 'js/photoswipe/photoswipe-ui-default' . $suffix . '.js', array('photoswipe'), '4.1.1', true); self::enqueue_style('photoswipe', $assets_path . 'css/photoswipe/photoswipe.css'); self::enqueue_style('photoswipe-default-skin', $assets_path . 'css/photoswipe/default-skin/default-skin.css'); self::enqueue_script('zoom', $assets_path . 'js/zoom/jquery.zoom' . $suffix . '.js', array('jquery'), '1.7.15', true); self::enqueue_script('wc-single-product'); wp_localize_script('wc-single-product', 'flexslider_options', apply_filters('woocommerce_single_product_carousel_options', array('rtl' => is_rtl(), 'animation' => 'slide', 'smoothHeight' => true, 'directionNav' => false, 'controlNav' => 'thumbnails', 'slideshow' => false, 'animationSpeed' => 500))); } if ('geolocation_ajax' === get_option('woocommerce_default_customer_address')) { // Exclude common bots from geolocation by user agent. $ua = wc_get_user_agent(); if (!strstr($ua, 'bot') && !strstr($ua, 'spider') && !strstr($ua, 'crawl')) { self::enqueue_script('wc-geolocation', $frontend_script_path . 'geolocation' . $suffix . '.js', array('jquery')); } } // Global frontend scripts self::enqueue_script('woocommerce', $frontend_script_path . 'woocommerce' . $suffix . '.js', array('jquery', 'jquery-blockui', 'js-cookie')); self::enqueue_script('wc-cart-fragments', $frontend_script_path . 'cart-fragments' . $suffix . '.js', array('jquery', 'js-cookie')); // CSS Styles if ($enqueue_styles = self::get_styles()) { foreach ($enqueue_styles as $handle => $args) { self::enqueue_style($handle, $args['src'], $args['deps'], $args['version'], $args['media']); } } // These are deprecated scripts only included for BW compatibility. @todo remove in future version. self::register_script('jquery-cookie', $assets_path . 'js/jquery-cookie/jquery.cookie' . $suffix . '.js', array('jquery'), '1.4.1'); self::register_script('prettyPhoto', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto' . $suffix . '.js', array('jquery'), '3.1.6', true); self::register_script('prettyPhoto-init', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto.init' . $suffix . '.js', array('jquery', 'prettyPhoto')); self::register_style('woocommerce_prettyPhoto_css', $assets_path . 'css/prettyPhoto.css'); }
/** * Register/queue frontend scripts. */ public static function load_scripts() { global $post; if (!did_action('before_woocommerce_init')) { return; } self::register_scripts(); self::register_styles(); if ('yes' === get_option('woocommerce_enable_ajax_add_to_cart')) { self::enqueue_script('wc-add-to-cart'); } if (is_cart()) { self::enqueue_script('wc-cart'); } if (is_checkout() || is_account_page()) { self::enqueue_script('select2'); self::enqueue_style('select2'); // Password strength meter. Load in checkout, account login and edit account page. if ('no' === get_option('woocommerce_registration_generate_password') && !is_user_logged_in() || is_edit_account_page() || is_lost_password_page()) { self::enqueue_script('wc-password-strength-meter'); } } if (is_checkout()) { self::enqueue_script('wc-checkout'); } if (is_add_payment_method_page()) { self::enqueue_script('wc-add-payment-method'); } if (is_lost_password_page()) { self::enqueue_script('wc-lost-password'); } if (is_product() || !empty($post->post_content) && strstr($post->post_content, '[product_page')) { self::enqueue_script('flexslider'); self::enqueue_script('photoswipe-ui-default'); self::enqueue_style('photoswipe-default-skin'); self::enqueue_script('zoom'); self::enqueue_script('wc-single-product'); } if ('geolocation_ajax' === get_option('woocommerce_default_customer_address')) { $ua = wc_get_user_agent(); // Exclude common bots from geolocation by user agent. if (!strstr($ua, 'bot') && !strstr($ua, 'spider') && !strstr($ua, 'crawl')) { self::enqueue_script('wc-geolocation'); } } // Global frontend scripts self::enqueue_script('woocommerce'); self::enqueue_script('wc-cart-fragments'); // CSS Styles if ($enqueue_styles = self::get_styles()) { foreach ($enqueue_styles as $handle => $args) { self::enqueue_style($handle, $args['src'], $args['deps'], $args['version'], $args['media']); } } }